mirror of https://github.com/apache/lucene.git
SOLR-13795: Managed schema should do a core reload in standalone mode.
Fixes #902
(cherry picked from commit 22e96697de
)
This commit is contained in:
parent
e734b40375
commit
95e54196fc
|
@ -135,6 +135,9 @@ Improvements
|
|||
|
||||
* SOLR-13771: Add -v and -m to ulimit section of reference guide and bin/solr checks (Erick Erickson)
|
||||
|
||||
* SOLR-13795: Managed schema operations should do a core reload in Solr standalone mode.
|
||||
(Thomas Wöckinger via David Smiley)
|
||||
|
||||
Bug Fixes
|
||||
----------------------
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ public class IndexSchema {
|
|||
|
||||
protected List<SchemaField> fieldsWithDefaultValue = new ArrayList<>();
|
||||
protected Collection<SchemaField> requiredFields = new HashSet<>();
|
||||
protected volatile DynamicField[] dynamicFields;
|
||||
protected DynamicField[] dynamicFields = new DynamicField[] {};
|
||||
public DynamicField[] getDynamicFields() { return dynamicFields; }
|
||||
|
||||
protected Map<String, SchemaField> dynamicFieldCache = new ConcurrentHashMap<>();
|
||||
|
@ -151,7 +151,7 @@ public class IndexSchema {
|
|||
protected Map<String, List<CopyField>> copyFieldsMap = new HashMap<>();
|
||||
public Map<String,List<CopyField>> getCopyFieldsMap() { return Collections.unmodifiableMap(copyFieldsMap); }
|
||||
|
||||
protected DynamicCopy[] dynamicCopyFields;
|
||||
protected DynamicCopy[] dynamicCopyFields = new DynamicCopy[] {};
|
||||
public DynamicCopy[] getDynamicCopyFields() { return dynamicCopyFields; }
|
||||
|
||||
private Map<FieldType, PayloadDecoder> decoders = new HashMap<>(); // cache to avoid scanning token filters repeatedly, unnecessarily
|
||||
|
@ -962,18 +962,12 @@ public class IndexSchema {
|
|||
private void incrementCopyFieldTargetCount(SchemaField dest) {
|
||||
copyFieldTargetCounts.put(dest, copyFieldTargetCounts.containsKey(dest) ? copyFieldTargetCounts.get(dest) + 1 : 1);
|
||||
}
|
||||
|
||||
private void registerDynamicCopyField( DynamicCopy dcopy ) {
|
||||
if( dynamicCopyFields == null ) {
|
||||
dynamicCopyFields = new DynamicCopy[] {dcopy};
|
||||
}
|
||||
else {
|
||||
DynamicCopy[] temp = new DynamicCopy[dynamicCopyFields.length+1];
|
||||
System.arraycopy(dynamicCopyFields,0,temp,0,dynamicCopyFields.length);
|
||||
temp[temp.length -1] = dcopy;
|
||||
dynamicCopyFields = temp;
|
||||
}
|
||||
log.trace("Dynamic Copy Field:" + dcopy);
|
||||
|
||||
private void registerDynamicCopyField(DynamicCopy dcopy) {
|
||||
DynamicCopy[] temp = new DynamicCopy[dynamicCopyFields.length + 1];
|
||||
System.arraycopy(dynamicCopyFields, 0, temp, 0, dynamicCopyFields.length);
|
||||
temp[temp.length - 1] = dcopy;
|
||||
dynamicCopyFields = temp;
|
||||
}
|
||||
|
||||
static SimilarityFactory readSimilarity(SolrResourceLoader loader, Node node) {
|
||||
|
@ -1337,11 +1331,9 @@ public class IndexSchema {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (null != dynamicCopyFields) {
|
||||
for (DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
if (dynamicCopy.getDestFieldName().equals(destField)) {
|
||||
fieldNames.add(dynamicCopy.getRegex());
|
||||
}
|
||||
for (DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
if (dynamicCopy.getDestFieldName().equals(destField)) {
|
||||
fieldNames.add(dynamicCopy.getRegex());
|
||||
}
|
||||
}
|
||||
return fieldNames;
|
||||
|
@ -1356,11 +1348,9 @@ public class IndexSchema {
|
|||
// This is useful when we need the maxSize param of each CopyField
|
||||
public List<CopyField> getCopyFieldsList(final String sourceField){
|
||||
final List<CopyField> result = new ArrayList<>();
|
||||
if (null != dynamicCopyFields) {
|
||||
for (DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
if (dynamicCopy.matches(sourceField)) {
|
||||
result.add(new CopyField(getField(sourceField), dynamicCopy.getTargetField(sourceField), dynamicCopy.maxChars));
|
||||
}
|
||||
for (DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
if (dynamicCopy.matches(sourceField)) {
|
||||
result.add(new CopyField(getField(sourceField), dynamicCopy.getTargetField(sourceField), dynamicCopy.maxChars));
|
||||
}
|
||||
}
|
||||
List<CopyField> fixedCopyFields = copyFieldsMap.get(sourceField);
|
||||
|
@ -1556,48 +1546,46 @@ public class IndexSchema {
|
|||
}
|
||||
}
|
||||
}
|
||||
if (null != dynamicCopyFields) {
|
||||
for (IndexSchema.DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
final String source = dynamicCopy.getRegex();
|
||||
final String destination = dynamicCopy.getDestFieldName();
|
||||
if ((null == requestedSourceFields || requestedSourceFields.contains(source))
|
||||
&& (null == requestedDestinationFields || requestedDestinationFields.contains(destination))) {
|
||||
SimpleOrderedMap<Object> dynamicCopyProps = new SimpleOrderedMap<>();
|
||||
for (IndexSchema.DynamicCopy dynamicCopy : dynamicCopyFields) {
|
||||
final String source = dynamicCopy.getRegex();
|
||||
final String destination = dynamicCopy.getDestFieldName();
|
||||
if ((null == requestedSourceFields || requestedSourceFields.contains(source))
|
||||
&& (null == requestedDestinationFields || requestedDestinationFields.contains(destination))) {
|
||||
SimpleOrderedMap<Object> dynamicCopyProps = new SimpleOrderedMap<>();
|
||||
|
||||
dynamicCopyProps.add(SOURCE, dynamicCopy.getRegex());
|
||||
if (showDetails) {
|
||||
IndexSchema.DynamicField sourceDynamicBase = dynamicCopy.getSourceDynamicBase();
|
||||
if (null != sourceDynamicBase) {
|
||||
dynamicCopyProps.add(SOURCE_DYNAMIC_BASE, sourceDynamicBase.getRegex());
|
||||
} else if (source.contains("*")) {
|
||||
List<String> sourceExplicitFields = new ArrayList<>();
|
||||
Pattern pattern = Pattern.compile(source.replace("*", ".*")); // glob->regex
|
||||
for (String field : fields.keySet()) {
|
||||
if (pattern.matcher(field).matches()) {
|
||||
sourceExplicitFields.add(field);
|
||||
}
|
||||
}
|
||||
if (sourceExplicitFields.size() > 0) {
|
||||
Collections.sort(sourceExplicitFields);
|
||||
dynamicCopyProps.add(SOURCE_EXPLICIT_FIELDS, sourceExplicitFields);
|
||||
dynamicCopyProps.add(SOURCE, dynamicCopy.getRegex());
|
||||
if (showDetails) {
|
||||
IndexSchema.DynamicField sourceDynamicBase = dynamicCopy.getSourceDynamicBase();
|
||||
if (null != sourceDynamicBase) {
|
||||
dynamicCopyProps.add(SOURCE_DYNAMIC_BASE, sourceDynamicBase.getRegex());
|
||||
} else if (source.contains("*")) {
|
||||
List<String> sourceExplicitFields = new ArrayList<>();
|
||||
Pattern pattern = Pattern.compile(source.replace("*", ".*")); // glob->regex
|
||||
for (String field : fields.keySet()) {
|
||||
if (pattern.matcher(field).matches()) {
|
||||
sourceExplicitFields.add(field);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dynamicCopyProps.add(DESTINATION, dynamicCopy.getDestFieldName());
|
||||
if (showDetails) {
|
||||
IndexSchema.DynamicField destDynamicBase = dynamicCopy.getDestDynamicBase();
|
||||
if (null != destDynamicBase) {
|
||||
dynamicCopyProps.add(DESTINATION_DYNAMIC_BASE, destDynamicBase.getRegex());
|
||||
if (sourceExplicitFields.size() > 0) {
|
||||
Collections.sort(sourceExplicitFields);
|
||||
dynamicCopyProps.add(SOURCE_EXPLICIT_FIELDS, sourceExplicitFields);
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != dynamicCopy.getMaxChars()) {
|
||||
dynamicCopyProps.add(MAX_CHARS, dynamicCopy.getMaxChars());
|
||||
}
|
||||
|
||||
copyFieldProperties.add(dynamicCopyProps);
|
||||
}
|
||||
|
||||
dynamicCopyProps.add(DESTINATION, dynamicCopy.getDestFieldName());
|
||||
if (showDetails) {
|
||||
IndexSchema.DynamicField destDynamicBase = dynamicCopy.getDestDynamicBase();
|
||||
if (null != destDynamicBase) {
|
||||
dynamicCopyProps.add(DESTINATION_DYNAMIC_BASE, destDynamicBase.getRegex());
|
||||
}
|
||||
}
|
||||
|
||||
if (0 != dynamicCopy.getMaxChars()) {
|
||||
dynamicCopyProps.add(MAX_CHARS, dynamicCopy.getMaxChars());
|
||||
}
|
||||
|
||||
copyFieldProperties.add(dynamicCopyProps);
|
||||
}
|
||||
}
|
||||
return copyFieldProperties;
|
||||
|
|
|
@ -81,7 +81,7 @@ import org.xml.sax.InputSource;
|
|||
/** Solr-managed schema - non-user-editable, but can be mutable via internal and external REST API requests. */
|
||||
public final class ManagedIndexSchema extends IndexSchema {
|
||||
|
||||
private boolean isMutable = false;
|
||||
private final boolean isMutable;
|
||||
|
||||
@Override public boolean isMutable() { return isMutable; }
|
||||
|
||||
|
@ -654,7 +654,7 @@ public final class ManagedIndexSchema extends IndexSchema {
|
|||
System.arraycopy(newSchema.dynamicFields, dfPos + 1, temp, dfPos, newSchema.dynamicFields.length - dfPos - 1);
|
||||
newSchema.dynamicFields = temp;
|
||||
} else {
|
||||
newSchema.dynamicFields = new DynamicField[0];
|
||||
newSchema.dynamicFields = new DynamicField[] {};
|
||||
}
|
||||
}
|
||||
// After removing all dynamic fields, rebuild affected dynamic copy fields.
|
||||
|
@ -840,26 +840,24 @@ public final class ManagedIndexSchema extends IndexSchema {
|
|||
boolean found = false;
|
||||
|
||||
if (null == destSchemaField || null == sourceSchemaField) { // Must be dynamic copy field
|
||||
if (dynamicCopyFields != null) {
|
||||
for (int i = 0 ; i < dynamicCopyFields.length ; ++i) {
|
||||
DynamicCopy dynamicCopy = dynamicCopyFields[i];
|
||||
if (source.equals(dynamicCopy.getRegex()) && dest.equals(dynamicCopy.getDestFieldName())) {
|
||||
found = true;
|
||||
SchemaField destinationPrototype = dynamicCopy.getDestination().getPrototype();
|
||||
if (copyFieldTargetCounts.containsKey(destinationPrototype)) {
|
||||
decrementCopyFieldTargetCount(destinationPrototype);
|
||||
}
|
||||
if (dynamicCopyFields.length > 1) {
|
||||
DynamicCopy[] temp = new DynamicCopy[dynamicCopyFields.length - 1];
|
||||
System.arraycopy(dynamicCopyFields, 0, temp, 0, i);
|
||||
// skip over the dynamic copy field to be deleted
|
||||
System.arraycopy(dynamicCopyFields, i + 1, temp, i, dynamicCopyFields.length - i - 1);
|
||||
dynamicCopyFields = temp;
|
||||
} else {
|
||||
dynamicCopyFields = null;
|
||||
}
|
||||
break;
|
||||
for (int i = 0; i < dynamicCopyFields.length; ++i) {
|
||||
DynamicCopy dynamicCopy = dynamicCopyFields[i];
|
||||
if (source.equals(dynamicCopy.getRegex()) && dest.equals(dynamicCopy.getDestFieldName())) {
|
||||
found = true;
|
||||
SchemaField destinationPrototype = dynamicCopy.getDestination().getPrototype();
|
||||
if (copyFieldTargetCounts.containsKey(destinationPrototype)) {
|
||||
decrementCopyFieldTargetCount(destinationPrototype);
|
||||
}
|
||||
if (dynamicCopyFields.length > 1) {
|
||||
DynamicCopy[] temp = new DynamicCopy[dynamicCopyFields.length - 1];
|
||||
System.arraycopy(dynamicCopyFields, 0, temp, 0, i);
|
||||
// skip over the dynamic copy field to be deleted
|
||||
System.arraycopy(dynamicCopyFields, i + 1, temp, i, dynamicCopyFields.length - i - 1);
|
||||
dynamicCopyFields = temp;
|
||||
} else {
|
||||
dynamicCopyFields = new DynamicCopy[] {};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else { // non-dynamic copy field directive
|
||||
|
|
|
@ -138,6 +138,7 @@ public class SchemaManager {
|
|||
//only for non cloud stuff
|
||||
managedIndexSchema.persistManagedSchema(false);
|
||||
core.setLatestSchema(managedIndexSchema);
|
||||
core.getCoreContainer().reload(core.getName());
|
||||
} catch (SolrException e) {
|
||||
log.warn(errorMsg);
|
||||
errors = singletonList(errorMsg + e.getMessage());
|
||||
|
|
|
@ -20,6 +20,7 @@ import java.io.File;
|
|||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -32,6 +33,8 @@ import org.apache.lucene.search.similarities.BM25Similarity;
|
|||
import org.apache.lucene.search.similarities.DFISimilarity;
|
||||
import org.apache.lucene.search.similarities.PerFieldSimilarityWrapper;
|
||||
import org.apache.lucene.search.similarities.Similarity;
|
||||
import org.apache.solr.client.solrj.SolrQuery;
|
||||
import org.apache.solr.client.solrj.request.schema.SchemaRequest;
|
||||
import org.apache.solr.common.SolrDocumentList;
|
||||
import org.apache.solr.core.CoreContainer;
|
||||
import org.apache.solr.core.SolrCore;
|
||||
|
@ -43,6 +46,7 @@ import org.apache.solr.util.RestTestBase;
|
|||
import org.apache.solr.util.RestTestHarness;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
|
@ -184,8 +188,6 @@ public class TestBulkSchemaAPI extends RestTestBase {
|
|||
response = restTestHarness.post("/schema", json(addFieldTypeAnalyzerWithClass + suffix));
|
||||
map = (Map) fromJSONString(response);
|
||||
assertNull(response, map.get("error"));
|
||||
|
||||
restTestHarness.checkAdminResponseStatus("/admin/cores?wt=xml&action=RELOAD&core=" + coreName, "0");
|
||||
|
||||
map = getObj(restTestHarness, "myNewTextFieldWithAnalyzerClass", "fieldTypes");
|
||||
assertNotNull(map);
|
||||
|
@ -901,6 +903,24 @@ public class TestBulkSchemaAPI extends RestTestBase {
|
|||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testAddNewFieldAndQuery() throws Exception {
|
||||
getSolrClient().add(Arrays.asList(
|
||||
sdoc("id", "1", "term_s", "tux")));
|
||||
|
||||
getSolrClient().commit(true, true);
|
||||
Map<String,Object> attrs = new HashMap<>();
|
||||
attrs.put("name", "newstringtestfield");
|
||||
attrs.put("type", "string");
|
||||
|
||||
new SchemaRequest.AddField(attrs).process(getSolrClient());
|
||||
|
||||
SolrQuery query = new SolrQuery("*:*");
|
||||
query.addFacetField("newstringtestfield");
|
||||
int size = getSolrClient().query(query).getResults().size();
|
||||
assertEquals(1, size);
|
||||
}
|
||||
|
||||
public void testSimilarityParser() throws Exception {
|
||||
RestTestHarness harness = restTestHarness;
|
||||
|
||||
|
|
|
@ -16,6 +16,10 @@
|
|||
*/
|
||||
package org.apache.solr.client.solrj.request;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
@ -47,10 +51,6 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
import org.restlet.ext.servlet.ServerServlet;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.anyOf;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
|
||||
/**
|
||||
* Test the functionality (accuracy and failure) of the methods exposed by the classes
|
||||
* {@link SchemaRequest} and {@link SchemaResponse}.
|
||||
|
@ -622,8 +622,6 @@ public class SchemaTest extends RestTestBase {
|
|||
SchemaResponse.UpdateResponse addFieldTypeResponse = addFieldTypeRequest.process(getSolrClient());
|
||||
assertValidSchemaResponse(addFieldTypeResponse);
|
||||
|
||||
restTestHarness.reload();
|
||||
|
||||
SchemaRequest.FieldType fieldTypeRequest = new SchemaRequest.FieldType(fieldTypeName);
|
||||
SchemaResponse.FieldTypeResponse newFieldTypeResponse = fieldTypeRequest.process(getSolrClient());
|
||||
assertValidSchemaResponse(newFieldTypeResponse);
|
||||
|
|
Loading…
Reference in New Issue