You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by sa...@apache.org on 2015/03/26 20:11:35 UTC
svn commit: r1669413 [1/2] - in /lucene/dev/branches/branch_5x: ./ solr/
solr/core/ solr/core/src/java/org/apache/solr/handler/
solr/core/src/java/org/apache/solr/schema/
solr/core/src/java/org/apache/solr/util/
solr/core/src/test/org/apache/solr/rest/...
Author: sarowe
Date: Thu Mar 26 19:11:35 2015
New Revision: 1669413
URL: http://svn.apache.org/r1669413
Log:
SOLR-6141: Schema API: Remove fields, dynamic fields, field types and copy fields; and replace fields, dynamic fields and field types (merged trunk r1667175,r1667579,r1669055,r1669173)
Modified:
lucene/dev/branches/branch_5x/ (props changed)
lucene/dev/branches/branch_5x/solr/ (props changed)
lucene/dev/branches/branch_5x/solr/CHANGES.txt (contents, props changed)
lucene/dev/branches/branch_5x/solr/core/ (props changed)
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaField.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java (contents, props changed)
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java
lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java
Modified: lucene/dev/branches/branch_5x/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/CHANGES.txt?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/CHANGES.txt (original)
+++ lucene/dev/branches/branch_5x/solr/CHANGES.txt Thu Mar 26 19:11:35 2015
@@ -126,6 +126,9 @@ New Features
json.facet={count1:{query:"price:[10 TO 20]"}, count2:{query:"color:blue AND popularity:[0 TO 50]"} }
json.facet={categories:{terms:{field:cat, sort:"x desc", facet:{x:"avg(price)", y:"sum(price)"}}}}
(yonik)
+
+* SOLR-6141: Schema API: Remove fields, dynamic fields, field types and copy
+ fields; and replace fields, dynamic fields and field types. (Steve Rowe)
* SOLR-7217: HTTP POST body is auto-detected when the client is curl and the content
type is form data (curl's default), allowing users to use curl to send
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/handler/SchemaHandler.java Thu Mar 26 19:11:35 2015
@@ -62,11 +62,9 @@ public class SchemaHandler extends Reque
}
break;
}
-
} else {
handleGET(req, rsp);
}
-
}
private void handleGET(SolrQueryRequest req, SolrQueryResponse rsp) {
@@ -165,6 +163,6 @@ public class SchemaHandler extends Reque
@Override
public String getDescription() {
- return "Edit schema.xml";
+ return "CRUD operations over the Solr schema";
}
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/IndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/IndexSchema.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/IndexSchema.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/IndexSchema.java Thu Mar 26 19:11:35 2015
@@ -756,7 +756,7 @@ public class IndexSchema {
}
/** Returns true if the given name has exactly one asterisk either at the start or end of the name */
- private static boolean isValidFieldGlob(String name) {
+ protected static boolean isValidFieldGlob(String name) {
if (name.startsWith("*") || name.endsWith("*")) {
int count = 0;
for (int pos = 0 ; pos < name.length() && -1 != (pos = name.indexOf('*', pos)) ; ++pos) ++count;
@@ -936,7 +936,7 @@ public class IndexSchema {
}
}
- private void registerExplicitSrcAndDestFields(String source, int maxChars, SchemaField destSchemaField, SchemaField sourceSchemaField) {
+ protected void registerExplicitSrcAndDestFields(String source, int maxChars, SchemaField destSchemaField, SchemaField sourceSchemaField) {
List<CopyField> copyFieldList = copyFieldsMap.get(source);
if (copyFieldList == null) {
copyFieldList = new ArrayList<>();
@@ -1109,6 +1109,8 @@ public class IndexSchema {
this.destDynamicBase = destDynamicBase;
}
+ public DynamicField getDestination() { return destination; }
+
public String getDestFieldName() { return destination.getRegex(); }
/**
@@ -1296,7 +1298,7 @@ public class IndexSchema {
if (df.matches(fieldName)) return df.prototype.getType();
}
return null;
- };
+ }
/**
@@ -1417,10 +1419,11 @@ public class IndexSchema {
List<SimpleOrderedMap<Object>> copyFieldProperties = new ArrayList<>();
SortedMap<String,List<CopyField>> sortedCopyFields = new TreeMap<>(copyFieldsMap);
for (List<CopyField> copyFields : sortedCopyFields.values()) {
+ copyFields = new ArrayList<>(copyFields);
Collections.sort(copyFields, new Comparator<CopyField>() {
@Override
public int compare(CopyField cf1, CopyField cf2) {
- // sources are all be the same, just sorting by destination here
+ // sources are all the same, just sorting by destination here
return cf1.getDestination().getName().compareTo(cf2.getDestination().getName());
}
});
@@ -1495,13 +1498,13 @@ public class IndexSchema {
* {@link #getSchemaUpdateLock()}.
*
* @param newField the SchemaField to add
- * @param persist to persist the schema or not or not
+ * @param persist to persist the schema or not
* @return a new IndexSchema based on this schema with newField added
* @see #newField(String, String, Map)
*/
public IndexSchema addField(SchemaField newField, boolean persist) {
- return addFields(Collections.singletonList(newField),Collections.EMPTY_MAP,persist );
- }
+ return addFields(Collections.singletonList(newField), Collections.EMPTY_MAP, persist );
+ }
public IndexSchema addField(SchemaField newField) {
return addField(newField, true);
@@ -1553,13 +1556,51 @@ public class IndexSchema {
/**
+ * Copies this schema, deletes the named fields from the copy.
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by
+ * {@link #getSchemaUpdateLock()}.
+ *
+ * @param names the names of the fields to delete
+ * @return a new IndexSchema based on this schema with the named fields deleted
+ */
+ public IndexSchema deleteFields(Collection<String> names) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
+ * Copies this schema, deletes the named field from the copy, creates a new field
+ * with the same name using the given args, then rebinds any referring copy fields
+ * to the replacement field.
+ *
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by {@link #getSchemaUpdateLock()}.
+ *
+ * @param fieldName The name of the field to be replaced
+ * @param replacementFieldType The field type of the replacement field
+ * @param replacementArgs Initialization params for the replacement field
+ * @return a new IndexSchema based on this schema with the named field replaced
+ */
+ public IndexSchema replaceField(String fieldName, FieldType replacementFieldType, Map<String,?> replacementArgs) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
* Copies this schema, adds the given dynamic fields to the copy,
* Requires synchronizing on the object returned by
* {@link #getSchemaUpdateLock()}.
*
* @param newDynamicFields the SchemaFields to add
* @param copyFieldNames 0 or more names of targets to copy this field to. The target fields must already exist.
- * @param persist to persist the schema or not or not
+ * @param persist to persist the schema or not
* @return a new IndexSchema based on this schema with newDynamicFields added
* @see #newDynamicField(String, String, Map)
*/
@@ -1573,21 +1614,79 @@ public class IndexSchema {
}
/**
- * Copies this schema and adds the new copy fields to the copy
+ * Copies this schema, deletes the named dynamic fields from the copy.
+ * <p>
+ * The schema will not be persisted.
+ * <p>
* Requires synchronizing on the object returned by
* {@link #getSchemaUpdateLock()}.
*
- * @param copyFields Key is the name of the source field name, value is a collection of target field names. Fields must exist.
- * @param persist to persist the schema or not or not
- * @return The new Schema with the copy fields added
+ * @param fieldNamePatterns the names of the dynamic fields to delete
+ * @return a new IndexSchema based on this schema with the named dynamic fields deleted
*/
- public IndexSchema addCopyFields(Map<String, Collection<String>> copyFields, boolean persist){
+ public IndexSchema deleteDynamicFields(Collection<String> fieldNamePatterns) {
String msg = "This IndexSchema is not mutable.";
log.error(msg);
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
/**
+ * Copies this schema, deletes the named dynamic field from the copy, creates a new dynamic
+ * field with the same field name pattern using the given args, then rebinds any referring
+ * dynamic copy fields to the replacement dynamic field.
+ *
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by {@link #getSchemaUpdateLock()}.
+ *
+ * @param fieldNamePattern The glob for the dynamic field to be replaced
+ * @param replacementFieldType The field type of the replacement dynamic field
+ * @param replacementArgs Initialization params for the replacement dynamic field
+ * @return a new IndexSchema based on this schema with the named dynamic field replaced
+ */
+ public ManagedIndexSchema replaceDynamicField
+ (String fieldNamePattern, FieldType replacementFieldType, Map<String,?> replacementArgs) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
+ * Copies this schema and adds the new copy fields to the copy
+ * Requires synchronizing on the object returned by
+ * {@link #getSchemaUpdateLock()}.
+ *
+ * @param copyFields Key is the name of the source field name, value is a collection of target field names. Fields must exist.
+ * @param persist to persist the schema or not
+ * @return The new Schema with the copy fields added
+ */
+ public IndexSchema addCopyFields(Map<String, Collection<String>> copyFields, boolean persist) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
+ * Copies this schema and deletes the given copy fields from the copy.
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by
+ * {@link #getSchemaUpdateLock()}.
+ *
+ * @param copyFields Key is the name of the source field name, value is a collection of target field names.
+ * Each corresponding copy field directives must exist.
+ * @return The new Schema with the copy fields deleted
+ */
+ public IndexSchema deleteCopyFields(Map<String, Collection<String>> copyFields) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+
+ /**
* Returns a SchemaField if the given fieldName does not already
* exist in this schema, and does not match any dynamic fields
* in this schema. The resulting SchemaField can be used in a call
@@ -1624,7 +1723,7 @@ public class IndexSchema {
}
/**
- * Returns the schema update lock that should be synchronzied on
+ * Returns the schema update lock that should be synchronized on
* to update the schema. Only applicable to mutable schemas.
*
* @return the schema update lock object to synchronize on
@@ -1656,7 +1755,7 @@ public class IndexSchema {
* {@link #getSchemaUpdateLock()}.
*
* @param fieldTypeList a list of FieldTypes to add
- * @param persist to persist the schema or not or not
+ * @param persist to persist the schema or not
* @return a new IndexSchema based on this schema with the new types added
* @see #newFieldType(String, String, Map)
*/
@@ -1664,6 +1763,43 @@ public class IndexSchema {
String msg = "This IndexSchema is not mutable.";
log.error(msg);
throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
+ * Copies this schema, deletes the named field types from the copy.
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by {@link #getSchemaUpdateLock()}.
+ *
+ * @param names the names of the field types to delete
+ * @return a new IndexSchema based on this schema with the named field types deleted
+ */
+ public IndexSchema deleteFieldTypes(Collection<String> names) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+
+ /**
+ * Copies this schema, deletes the named field type from the copy, creates a new field type
+ * with the same name using the given args, rebuilds fields and dynamic fields of the given
+ * type, then rebinds any referring copy fields to the rebuilt fields.
+ *
+ * <p>
+ * The schema will not be persisted.
+ * <p>
+ * Requires synchronizing on the object returned by {@link #getSchemaUpdateLock()}.
+ *
+ * @param typeName The name of the field type to be replaced
+ * @param replacementClassName The class name of the replacement field type
+ * @param replacementArgs Initialization params for the replacement field type
+ * @return a new IndexSchema based on this schema with the named field type replaced
+ */
+ public IndexSchema replaceFieldType(String typeName, String replacementClassName, Map<String,Object> replacementArgs) {
+ String msg = "This IndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
/**
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchema.java Thu Mar 26 19:11:35 2015
@@ -68,6 +68,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -386,7 +387,7 @@ public final class ManagedIndexSchema ex
public ManagedIndexSchema addFields(Collection<SchemaField> newFields,
Map<String, Collection<String>> copyFieldNames,
boolean persist) {
- ManagedIndexSchema newSchema = null;
+ ManagedIndexSchema newSchema;
if (isMutable) {
boolean success = false;
if (copyFieldNames == null){
@@ -440,11 +441,136 @@ public final class ManagedIndexSchema ex
return newSchema;
}
+ @Override
+ public ManagedIndexSchema deleteFields(Collection<String> names) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ newSchema = shallowCopy(true);
+ for (String name : names) {
+ SchemaField field = getFieldOrNull(name);
+ if (null != field) {
+ String message = "Can't delete field '" + name
+ + "' because it's referred to by at least one copy field directive.";
+ if (newSchema.copyFieldsMap.containsKey(name) || newSchema.isCopyFieldTarget(field)) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, message);
+ }
+ for (int i = 0 ; i < newSchema.dynamicCopyFields.length ; ++i) {
+ DynamicCopy dynamicCopy = newSchema.dynamicCopyFields[i];
+ if (name.equals(dynamicCopy.getRegex())) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, message);
+ }
+ }
+ newSchema.fields.remove(name);
+ newSchema.fieldsWithDefaultValue.remove(field);
+ newSchema.requiredFields.remove(field);
+ } else {
+ String msg = "The field '" + name + "' is not present in this schema, and so cannot be deleted.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ }
+ // Run the callbacks on SchemaAware now that everything else is done
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
@Override
+ public ManagedIndexSchema replaceField
+ (String fieldName, FieldType replacementFieldType, Map<String,?> replacementArgs) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ SchemaField oldField = fields.get(fieldName);
+ if (null == oldField) {
+ String msg = "The field '" + fieldName + "' is not present in this schema, and so cannot be replaced.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ newSchema = shallowCopy(true);
+ // clone data structures before modifying them
+ newSchema.copyFieldsMap = cloneCopyFieldsMap(copyFieldsMap);
+ newSchema.copyFieldTargetCounts
+ = (Map<SchemaField,Integer>)((HashMap<SchemaField,Integer>)copyFieldTargetCounts).clone();
+ newSchema.dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length];
+ System.arraycopy(dynamicCopyFields, 0, newSchema.dynamicCopyFields, 0, dynamicCopyFields.length);
+
+ // Drop the old field
+ newSchema.fields.remove(fieldName);
+ newSchema.fieldsWithDefaultValue.remove(oldField);
+ newSchema.requiredFields.remove(oldField);
+
+ // Add the replacement field
+ SchemaField replacementField = SchemaField.create(fieldName, replacementFieldType, replacementArgs);
+ newSchema.fields.put(fieldName, replacementField);
+ if (null != replacementField.getDefaultValue()) {
+ log.debug(replacementField.getName() + " contains default value: " + replacementField.getDefaultValue());
+ newSchema.fieldsWithDefaultValue.add(replacementField);
+ }
+ if (replacementField.isRequired()) {
+ log.debug("{} is required in this schema", replacementField.getName());
+ newSchema.requiredFields.add(replacementField);
+ }
+
+ List<CopyField> copyFieldsToRebuild = new ArrayList<>();
+ newSchema.removeCopyFieldSource(fieldName, copyFieldsToRebuild);
+
+ newSchema.copyFieldTargetCounts.remove(oldField); // zero out target count for this field
+
+ // Remove copy fields where the target is this field; remember them to rebuild
+ for (Map.Entry<String,List<CopyField>> entry : newSchema.copyFieldsMap.entrySet()) {
+ List<CopyField> perSourceCopyFields = entry.getValue();
+ Iterator<CopyField> checkDestCopyFieldsIter = perSourceCopyFields.iterator();
+ while (checkDestCopyFieldsIter.hasNext()) {
+ CopyField checkDestCopyField = checkDestCopyFieldsIter.next();
+ if (fieldName.equals(checkDestCopyField.getDestination().getName())) {
+ checkDestCopyFieldsIter.remove();
+ copyFieldsToRebuild.add(checkDestCopyField);
+ }
+ }
+ }
+ newSchema.rebuildCopyFields(copyFieldsToRebuild);
+
+ // Find dynamic copy fields where the source or destination is this field; remember them to rebuild
+ List<DynamicCopy> dynamicCopyFieldsToRebuild = new ArrayList<>();
+ List<DynamicCopy> newDynamicCopyFields = new ArrayList<>();
+ for (int i = 0 ; i < newSchema.dynamicCopyFields.length ; ++i) {
+ DynamicCopy dynamicCopy = newSchema.dynamicCopyFields[i];
+ SchemaField destinationPrototype = dynamicCopy.getDestination().getPrototype();
+ if (fieldName.equals(dynamicCopy.getRegex()) || fieldName.equals(destinationPrototype.getName())) {
+ dynamicCopyFieldsToRebuild.add(dynamicCopy);
+ } else {
+ newDynamicCopyFields.add(dynamicCopy);
+ }
+ }
+ // Rebuild affected dynamic copy fields
+ if (dynamicCopyFieldsToRebuild.size() > 0) {
+ newSchema.dynamicCopyFields = newDynamicCopyFields.toArray(new DynamicCopy[newDynamicCopyFields.size()]);
+ for (DynamicCopy dynamicCopy : dynamicCopyFieldsToRebuild) {
+ newSchema.registerCopyField(dynamicCopy.getRegex(), dynamicCopy.getDestFieldName(), dynamicCopy.getMaxChars());
+ }
+ }
+
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
+ @Override
public ManagedIndexSchema addDynamicFields(Collection<SchemaField> newDynamicFields,
Map<String,Collection<String>> copyFieldNames, boolean persist) {
- ManagedIndexSchema newSchema = null;
+ ManagedIndexSchema newSchema;
if (isMutable) {
boolean success = false;
if (copyFieldNames == null){
@@ -474,7 +600,7 @@ public final class ManagedIndexSchema ex
aware.inform(newSchema);
}
newSchema.refreshAnalyzers();
- if(persist) {
+ if (persist) {
success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
if (success) {
log.debug("Added dynamic field(s): {}", newDynamicFields);
@@ -491,8 +617,152 @@ public final class ManagedIndexSchema ex
}
@Override
+ public ManagedIndexSchema deleteDynamicFields(Collection<String> fieldNamePatterns) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ newSchema = shallowCopy(true);
+
+ newSchema.dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length];
+ System.arraycopy(dynamicCopyFields, 0, newSchema.dynamicCopyFields, 0, dynamicCopyFields.length);
+
+ List<DynamicCopy> dynamicCopyFieldsToRebuild = new ArrayList<>();
+ List<DynamicCopy> newDynamicCopyFields = new ArrayList<>();
+
+ for (String fieldNamePattern : fieldNamePatterns) {
+ DynamicField dynamicField = null;
+ int dfPos = 0;
+ for ( ; dfPos < newSchema.dynamicFields.length ; ++dfPos) {
+ DynamicField df = newSchema.dynamicFields[dfPos];
+ if (df.getRegex().equals(fieldNamePattern)) {
+ dynamicField = df;
+ break;
+ }
+ }
+ if (null == dynamicField) {
+ String msg = "The dynamic field '" + fieldNamePattern
+ + "' is not present in this schema, and so cannot be deleted.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ for (int i = 0 ; i < newSchema.dynamicCopyFields.length ; ++i) {
+ DynamicCopy dynamicCopy = newSchema.dynamicCopyFields[i];
+ DynamicField destDynamicBase = dynamicCopy.getDestDynamicBase();
+ DynamicField sourceDynamicBase = dynamicCopy.getSourceDynamicBase();
+ if ((null != destDynamicBase && fieldNamePattern.equals(destDynamicBase.getRegex()))
+ || (null != sourceDynamicBase && fieldNamePattern.equals(sourceDynamicBase.getRegex()))
+ || dynamicField.matches(dynamicCopy.getRegex())
+ || dynamicField.matches(dynamicCopy.getDestFieldName())) {
+ dynamicCopyFieldsToRebuild.add(dynamicCopy);
+ newSchema.decrementCopyFieldTargetCount(dynamicCopy.getDestination().getPrototype());
+ // don't add this dynamic copy field to newDynamicCopyFields - effectively removing it
+ } else {
+ newDynamicCopyFields.add(dynamicCopy);
+ }
+ }
+ if (newSchema.dynamicFields.length > 1) {
+ DynamicField[] temp = new DynamicField[newSchema.dynamicFields.length - 1];
+ System.arraycopy(newSchema.dynamicFields, 0, temp, 0, dfPos);
+ // skip over the dynamic field to be deleted
+ System.arraycopy(newSchema.dynamicFields, dfPos + 1, temp, dfPos, newSchema.dynamicFields.length - dfPos - 1);
+ newSchema.dynamicFields = temp;
+ } else {
+ newSchema.dynamicFields = new DynamicField[0];
+ }
+ }
+ // After removing all dynamic fields, rebuild affected dynamic copy fields.
+ // This may trigger an exception, if one of the deleted dynamic fields was the only matching source or target.
+ if (dynamicCopyFieldsToRebuild.size() > 0) {
+ newSchema.dynamicCopyFields = newDynamicCopyFields.toArray(new DynamicCopy[newDynamicCopyFields.size()]);
+ for (DynamicCopy dynamicCopy : dynamicCopyFieldsToRebuild) {
+ newSchema.registerCopyField(dynamicCopy.getRegex(), dynamicCopy.getDestFieldName(), dynamicCopy.getMaxChars());
+ }
+ }
+
+ // Run the callbacks on SchemaAware now that everything else is done
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
+ @Override
+ public ManagedIndexSchema replaceDynamicField
+ (String fieldNamePattern, FieldType replacementFieldType, Map<String,?> replacementArgs) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ DynamicField oldDynamicField = null;
+ int dfPos = 0;
+ for ( ; dfPos < dynamicFields.length ; ++dfPos) {
+ DynamicField dynamicField = dynamicFields[dfPos];
+ if (dynamicField.getRegex().equals(fieldNamePattern)) {
+ oldDynamicField = dynamicField;
+ break;
+ }
+ }
+ if (null == oldDynamicField) {
+ String msg = "The dynamic field '" + fieldNamePattern
+ + "' is not present in this schema, and so cannot be replaced.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+
+ newSchema = shallowCopy(true);
+
+ // clone data structures before modifying them
+ newSchema.copyFieldTargetCounts
+ = (Map<SchemaField,Integer>)((HashMap<SchemaField,Integer>)copyFieldTargetCounts).clone();
+ newSchema.dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length];
+ System.arraycopy(dynamicCopyFields, 0, newSchema.dynamicCopyFields, 0, dynamicCopyFields.length);
+
+ // Put the replacement dynamic field in place
+ SchemaField prototype = SchemaField.create(fieldNamePattern, replacementFieldType, replacementArgs);
+ newSchema.dynamicFields[dfPos] = new DynamicField(prototype);
+
+ // Find dynamic copy fields where this dynamic field is the source or target base; remember them to rebuild
+ List<DynamicCopy> dynamicCopyFieldsToRebuild = new ArrayList<>();
+ List<DynamicCopy> newDynamicCopyFields = new ArrayList<>();
+ for (int i = 0 ; i < newSchema.dynamicCopyFields.length ; ++i) {
+ DynamicCopy dynamicCopy = newSchema.dynamicCopyFields[i];
+ DynamicField destDynamicBase = dynamicCopy.getDestDynamicBase();
+ DynamicField sourceDynamicBase = dynamicCopy.getSourceDynamicBase();
+ if (fieldNamePattern.equals(dynamicCopy.getRegex())
+ || fieldNamePattern.equals(dynamicCopy.getDestFieldName())
+ || (null != destDynamicBase && fieldNamePattern.equals(destDynamicBase.getRegex()))
+ || (null != sourceDynamicBase && fieldNamePattern.equals(sourceDynamicBase.getRegex()))) {
+ dynamicCopyFieldsToRebuild.add(dynamicCopy);
+ newSchema.decrementCopyFieldTargetCount(dynamicCopy.getDestination().getPrototype());
+ // don't add this dynamic copy field to newDynamicCopyFields - effectively removing it
+ } else {
+ newDynamicCopyFields.add(dynamicCopy);
+ }
+ }
+ // Rebuild affected dynamic copy fields
+ if (dynamicCopyFieldsToRebuild.size() > 0) {
+ newSchema.dynamicCopyFields = newDynamicCopyFields.toArray(new DynamicCopy[newDynamicCopyFields.size()]);
+ for (DynamicCopy dynamicCopy : dynamicCopyFieldsToRebuild) {
+ newSchema.registerCopyField(dynamicCopy.getRegex(), dynamicCopy.getDestFieldName(), dynamicCopy.getMaxChars());
+ }
+ }
+
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
+ @Override
public ManagedIndexSchema addCopyFields(Map<String, Collection<String>> copyFields, boolean persist) {
- ManagedIndexSchema newSchema = null;
+ ManagedIndexSchema newSchema;
if (isMutable) {
boolean success = false;
newSchema = shallowCopy(true);
@@ -517,9 +787,152 @@ public final class ManagedIndexSchema ex
log.error("Failed to add copy fields for {} sources", copyFields.size());
}
}
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
+ @Override
+ public ManagedIndexSchema deleteCopyFields(Map<String,Collection<String>> copyFields) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ newSchema = shallowCopy(true);
+ // clone data structures before modifying them
+ newSchema.copyFieldsMap = cloneCopyFieldsMap(copyFieldsMap);
+ newSchema.copyFieldTargetCounts
+ = (Map<SchemaField,Integer>)((HashMap<SchemaField,Integer>)copyFieldTargetCounts).clone();
+ newSchema.dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length];
+ System.arraycopy(dynamicCopyFields, 0, newSchema.dynamicCopyFields, 0, dynamicCopyFields.length);
+
+ for (Map.Entry<String,Collection<String>> entry : copyFields.entrySet()) {
+ // Key is the source, values are the destinations
+ for (String destination : entry.getValue()) {
+ newSchema.deleteCopyField(entry.getKey(), destination);
+ }
+ }
+ //TODO: move this common stuff out to shared methods
+ // Run the callbacks on SchemaAware now that everything else is done
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
}
return newSchema;
}
+
+ private void deleteCopyField(String source, String dest) {
+ // Assumption: a copy field directive will exist only if the source & destination (dynamic) fields exist
+ SchemaField destSchemaField = fields.get(dest);
+ SchemaField sourceSchemaField = fields.get(source);
+
+ final String invalidGlobMessage = "is an invalid glob: either it contains more than one asterisk,"
+ + " or the asterisk occurs neither at the start nor at the end.";
+ if (source.contains("*") && ! isValidFieldGlob(source)) {
+ String msg = "copyField source '" + source + "' " + invalidGlobMessage;
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ if (dest.contains("*") && ! isValidFieldGlob(dest)) {
+ String msg = "copyField dest '" + dest + "' " + invalidGlobMessage;
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+
+ 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;
+ }
+ }
+ }
+ } else { // non-dynamic copy field directive
+ List<CopyField> copyFieldList = copyFieldsMap.get(source);
+ if (copyFieldList != null) {
+ for (Iterator<CopyField> iter = copyFieldList.iterator() ; iter.hasNext() ; ) {
+ CopyField copyField = iter.next();
+ if (dest.equals(copyField.getDestination().getName())) {
+ found = true;
+ decrementCopyFieldTargetCount(copyField.getDestination());
+ iter.remove();
+ if (copyFieldList.isEmpty()) {
+ copyFieldsMap.remove(source);
+ }
+ break;
+ }
+ }
+ }
+ }
+ if ( ! found) {
+ throw new SolrException(ErrorCode.BAD_REQUEST,
+ "Copy field directive not found: '" + source + "' -> '" + dest + "'");
+ }
+ }
+
+ /**
+ * Removes all copy fields with the given source field name, decrements the count for the copy field target,
+ * and adds the removed copy fields to removedCopyFields.
+ */
+ private void removeCopyFieldSource(String sourceFieldName, List<CopyField> removedCopyFields) {
+ List<CopyField> sourceCopyFields = copyFieldsMap.remove(sourceFieldName);
+ if (null != sourceCopyFields) {
+ for (CopyField sourceCopyField : sourceCopyFields) {
+ decrementCopyFieldTargetCount(sourceCopyField.getDestination());
+ removedCopyFields.add(sourceCopyField);
+ }
+ }
+ }
+
+ /**
+ * Registers new copy fields with the source, destination and maxChars taken from each of the oldCopyFields.
+ *
+ * Assumption: the fields in oldCopyFields still exist in the schema.
+ */
+ private void rebuildCopyFields(List<CopyField> oldCopyFields) {
+ if (oldCopyFields.size() > 0) {
+ for (CopyField copyField : oldCopyFields) {
+ SchemaField source = fields.get(copyField.getSource().getName());
+ SchemaField destination = fields.get(copyField.getDestination().getName());
+ registerExplicitSrcAndDestFields
+ (copyField.getSource().getName(), copyField.getMaxChars(), destination, source);
+ }
+ }
+ }
+
+ /**
+ * Decrements the count for the given destination field in copyFieldTargetCounts.
+ */
+ private void decrementCopyFieldTargetCount(SchemaField dest) {
+ Integer count = copyFieldTargetCounts.get(dest);
+ assert count != null;
+ if (count <= 1) {
+ copyFieldTargetCounts.remove(dest);
+ } else {
+ copyFieldTargetCounts.put(dest, count - 1);
+ }
+ }
public ManagedIndexSchema addFieldTypes(List<FieldType> fieldTypeList, boolean persist) {
if (!isMutable) {
@@ -579,6 +992,182 @@ public final class ManagedIndexSchema ex
return newSchema;
}
+ @Override
+ public ManagedIndexSchema deleteFieldTypes(Collection<String> names) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ for (String name : names) {
+ if ( ! fieldTypes.containsKey(name)) {
+ String msg = "The field type '" + name + "' is not present in this schema, and so cannot be deleted.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ for (SchemaField field : fields.values()) {
+ if (field.getType().getTypeName().equals(name)) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, "Can't delete '" + name
+ + "' because it's the field type of field '" + field.getName() + "'.");
+ }
+ }
+ for (DynamicField dynamicField : dynamicFields) {
+ if (dynamicField.getPrototype().getType().getTypeName().equals(name)) {
+ throw new SolrException(ErrorCode.BAD_REQUEST, "Can't delete '" + name
+ + "' because it's the field type of dynamic field '" + dynamicField.getRegex() + "'.");
+ }
+ }
+ }
+ newSchema = shallowCopy(true);
+ for (String name : names) {
+ newSchema.fieldTypes.remove(name);
+ }
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ for (FieldType fieldType : newSchema.fieldTypes.values()) {
+ informResourceLoaderAwareObjectsForFieldType(fieldType);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
+ private Map<String,List<CopyField>> cloneCopyFieldsMap(Map<String,List<CopyField>> original) {
+ Map<String,List<CopyField>> clone = new HashMap<>(original.size());
+ Iterator<Map.Entry<String,List<CopyField>>> iterator = original.entrySet().iterator();
+ while (iterator.hasNext()) {
+ Map.Entry<String,List<CopyField>> entry = iterator.next();
+ clone.put(entry.getKey(), new ArrayList<>(entry.getValue()));
+ }
+ return clone;
+ }
+
+ @Override
+ public ManagedIndexSchema replaceFieldType(String typeName, String replacementClassName, Map<String,Object> replacementArgs) {
+ ManagedIndexSchema newSchema;
+ if (isMutable) {
+ if ( ! fieldTypes.containsKey(typeName)) {
+ String msg = "The field type '" + typeName + "' is not present in this schema, and so cannot be replaced.";
+ throw new SolrException(ErrorCode.BAD_REQUEST, msg);
+ }
+ newSchema = shallowCopy(true);
+ // clone data structures before modifying them
+ newSchema.fieldTypes = (Map<String,FieldType>)((HashMap<String,FieldType>)fieldTypes).clone();
+ newSchema.copyFieldsMap = cloneCopyFieldsMap(copyFieldsMap);
+ newSchema.copyFieldTargetCounts
+ = (Map<SchemaField,Integer>)((HashMap<SchemaField,Integer>)copyFieldTargetCounts).clone();
+ newSchema.dynamicCopyFields = new DynamicCopy[dynamicCopyFields.length];
+ System.arraycopy(dynamicCopyFields, 0, newSchema.dynamicCopyFields, 0, dynamicCopyFields.length);
+ newSchema.dynamicFields = new DynamicField[dynamicFields.length];
+ System.arraycopy(dynamicFields, 0, newSchema.dynamicFields, 0, dynamicFields.length);
+
+ newSchema.fieldTypes.remove(typeName);
+ FieldType replacementFieldType = newSchema.newFieldType(typeName, replacementClassName, replacementArgs);
+ newSchema.fieldTypes.put(typeName, replacementFieldType);
+
+ // Rebuild fields of the type being replaced
+ List<CopyField> copyFieldsToRebuild = new ArrayList<>();
+ List<SchemaField> replacementFields = new ArrayList<>();
+ Iterator<Map.Entry<String,SchemaField>> fieldsIter = newSchema.fields.entrySet().iterator();
+ while (fieldsIter.hasNext()) {
+ Map.Entry<String,SchemaField> entry = fieldsIter.next();
+ SchemaField oldField = entry.getValue();
+ if (oldField.getType().getTypeName().equals(typeName)) {
+ String fieldName = oldField.getName();
+
+ // Drop the old field
+ fieldsIter.remove();
+ newSchema.fieldsWithDefaultValue.remove(oldField);
+ newSchema.requiredFields.remove(oldField);
+
+ // Add the replacement field
+ SchemaField replacementField = SchemaField.create(fieldName, replacementFieldType, oldField.getArgs());
+ replacementFields.add(replacementField); // Save the new field to be added after iteration is finished
+ if (null != replacementField.getDefaultValue()) {
+ log.debug(replacementField.getName() + " contains default value: " + replacementField.getDefaultValue());
+ newSchema.fieldsWithDefaultValue.add(replacementField);
+ }
+ if (replacementField.isRequired()) {
+ log.debug("{} is required in this schema", replacementField.getName());
+ newSchema.requiredFields.add(replacementField);
+ }
+ newSchema.removeCopyFieldSource(fieldName, copyFieldsToRebuild);
+ }
+ }
+ for (SchemaField replacementField : replacementFields) {
+ newSchema.fields.put(replacementField.getName(), replacementField);
+ }
+ // Remove copy fields where the target is of the type being replaced; remember them to rebuild
+ Iterator<Map.Entry<String,List<CopyField>>> copyFieldsMapIter = newSchema.copyFieldsMap.entrySet().iterator();
+ while (copyFieldsMapIter.hasNext()) {
+ Map.Entry<String,List<CopyField>> entry = copyFieldsMapIter.next();
+ List<CopyField> perSourceCopyFields = entry.getValue();
+ Iterator<CopyField> checkDestCopyFieldsIter = perSourceCopyFields.iterator();
+ while (checkDestCopyFieldsIter.hasNext()) {
+ CopyField checkDestCopyField = checkDestCopyFieldsIter.next();
+ SchemaField destination = checkDestCopyField.getDestination();
+ if (typeName.equals(destination.getType().getTypeName())) {
+ checkDestCopyFieldsIter.remove();
+ copyFieldsToRebuild.add(checkDestCopyField);
+ newSchema.copyFieldTargetCounts.remove(destination); // zero out target count
+ }
+ }
+ if (perSourceCopyFields.isEmpty()) {
+ copyFieldsMapIter.remove();
+ }
+ }
+ // Rebuild dynamic fields of the type being replaced
+ for (int i = 0; i < newSchema.dynamicFields.length; ++i) {
+ SchemaField prototype = newSchema.dynamicFields[i].getPrototype();
+ if (typeName.equals(prototype.getType().getTypeName())) {
+ newSchema.dynamicFields[i] = new DynamicField
+ (SchemaField.create(prototype.getName(), replacementFieldType, prototype.getArgs()));
+ }
+ }
+ // Find dynamic copy fields where the destination field's type is being replaced
+ // or the source dynamic base's type is being replaced; remember them to rebuild
+ List<DynamicCopy> dynamicCopyFieldsToRebuild = new ArrayList<>();
+ List<DynamicCopy> newDynamicCopyFields = new ArrayList<>();
+ for (int i = 0 ; i < newSchema.dynamicCopyFields.length ; ++i) {
+ DynamicCopy dynamicCopy = newSchema.dynamicCopyFields[i];
+ DynamicField sourceDynamicBase = dynamicCopy.getSourceDynamicBase();
+ SchemaField destinationPrototype = dynamicCopy.getDestination().getPrototype();
+ if (typeName.equals(destinationPrototype.getType().getTypeName())
+ || (null != sourceDynamicBase && typeName.equals(sourceDynamicBase.getPrototype().getType().getTypeName()))) {
+ dynamicCopyFieldsToRebuild.add(dynamicCopy);
+ if (newSchema.copyFieldTargetCounts.containsKey(destinationPrototype)) {
+ newSchema.decrementCopyFieldTargetCount(destinationPrototype);
+ }
+ // don't add this dynamic copy field to newDynamicCopyFields - effectively removing it
+ } else {
+ newDynamicCopyFields.add(dynamicCopy);
+ }
+ }
+ // Rebuild affected dynamic copy fields
+ if (dynamicCopyFieldsToRebuild.size() > 0) {
+ newSchema.dynamicCopyFields = newDynamicCopyFields.toArray(new DynamicCopy[newDynamicCopyFields.size()]);
+ for (DynamicCopy dynamicCopy : dynamicCopyFieldsToRebuild) {
+ newSchema.registerCopyField(dynamicCopy.getRegex(), dynamicCopy.getDestFieldName(), dynamicCopy.getMaxChars());
+ }
+ }
+ newSchema.rebuildCopyFields(copyFieldsToRebuild);
+
+ for (SchemaAware aware : newSchema.schemaAware) {
+ aware.inform(newSchema);
+ }
+ for (FieldType fieldType : newSchema.fieldTypes.values()) {
+ newSchema.informResourceLoaderAwareObjectsForFieldType(fieldType);
+ }
+ newSchema.refreshAnalyzers();
+ } else {
+ String msg = "This ManagedIndexSchema is not mutable.";
+ log.error(msg);
+ throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+ }
+ return newSchema;
+ }
+
/**
* Informs analyzers used by a fieldType.
*/
@@ -696,8 +1285,8 @@ public final class ManagedIndexSchema ex
// build the new FieldType using the existing FieldTypePluginLoader framework
// which expects XML, so we use a JSON to XML adapter to transform the JSON object
// provided in the request into the XML format supported by the plugin loader
- Map<String, FieldType> newFieldTypes = new HashMap<String, FieldType>();
- List<SchemaAware> schemaAwareList = new ArrayList<SchemaAware>();
+ Map<String,FieldType> newFieldTypes = new HashMap<>();
+ List<SchemaAware> schemaAwareList = new ArrayList<>();
FieldTypePluginLoader typeLoader = new FieldTypePluginLoader(this, newFieldTypes, schemaAwareList);
typeLoader.loadSingle(loader, FieldTypeXmlAdapter.toNode(options));
FieldType ft = newFieldTypes.get(typeName);
@@ -749,56 +1338,6 @@ public final class ManagedIndexSchema ex
}
}
-
- /**
- * Called from ZkIndexSchemaReader to merge the fields from the serialized managed schema
- * on ZooKeeper with the local managed schema.
- *
- * @param inputSource The serialized content of the managed schema from ZooKeeper
- * @param schemaZkVersion The ZK version of the managed schema on ZooKeeper
- * @return The new merged schema
- */
- ManagedIndexSchema reloadFields(InputSource inputSource, int schemaZkVersion) {
- ManagedIndexSchema newSchema;
- try {
- newSchema = shallowCopy(false);
- Config schemaConf = new Config(loader, SCHEMA, inputSource, SLASH+SCHEMA+SLASH);
- Document document = schemaConf.getDocument();
- final XPath xpath = schemaConf.getXPath();
-
- // create a unified collection of field types from zk and in the local
- newSchema.mergeFieldTypesFromZk(document, xpath);
-
- newSchema.loadFields(document, xpath);
- // let's completely rebuild the copy fields from the schema in ZK.
- // create new copyField-related objects so we don't affect the
- // old schema
- newSchema.copyFieldsMap = new HashMap<>();
- newSchema.dynamicCopyFields = new DynamicCopy[] {};
- newSchema.copyFieldTargetCounts = new HashMap<>();
- newSchema.loadCopyFields(document, xpath);
- if (null != uniqueKeyField) {
- newSchema.requiredFields.add(uniqueKeyField);
- }
- //Run the callbacks on SchemaAware now that everything else is done
- for (SchemaAware aware : newSchema.schemaAware) {
- aware.inform(newSchema);
- }
-
- // notify analyzers and other objects for our fieldTypes
- for (FieldType fieldType : newSchema.fieldTypes.values())
- informResourceLoaderAwareObjectsForFieldType(fieldType);
-
- newSchema.refreshAnalyzers();
- newSchema.schemaZkVersion = schemaZkVersion;
- } catch (SolrException e) {
- throw e;
- } catch (Exception e) {
- throw new SolrException(ErrorCode.SERVER_ERROR, "Schema Parsing Failed: " + e.getMessage(), e);
- }
- return newSchema;
- }
-
private ManagedIndexSchema(final SolrConfig solrConfig, final SolrResourceLoader loader, boolean isMutable,
String managedSchemaResourceName, int schemaZkVersion, Object schemaUpdateLock)
throws KeeperException, InterruptedException {
@@ -872,23 +1411,4 @@ public final class ManagedIndexSchema ex
public Object getSchemaUpdateLock() {
return schemaUpdateLock;
}
-
- /**
- * Loads FieldType objects defined in the schema.xml document.
- *
- * @param document Schema XML document where field types are defined.
- * @param xpath Used for evaluating xpath expressions to find field types defined in the schema.xml.
- * @throws javax.xml.xpath.XPathExpressionException if an error occurs when finding field type elements in the document.
- */
- protected synchronized void mergeFieldTypesFromZk(Document document, XPath xpath)
- throws XPathExpressionException
- {
- Map<String, FieldType> newFieldTypes = new HashMap<String, FieldType>();
- FieldTypePluginLoader typeLoader = new FieldTypePluginLoader(this, newFieldTypes, schemaAware);
- String expression = getFieldTypeXPathExpressions();
- NodeList nodes = (NodeList) xpath.evaluate(expression, document, XPathConstants.NODESET);
- typeLoader.load(loader, nodes);
- for (String newTypeName : newFieldTypes.keySet())
- fieldTypes.put(newTypeName, newFieldTypes.get(newTypeName));
- }
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ManagedIndexSchemaFactory.java Thu Mar 26 19:11:35 2015
@@ -404,4 +404,12 @@ public class ManagedIndexSchemaFactory e
this.schema = schema;
core.setLatestSchema(schema);
}
+
+ public boolean isMutable() {
+ return isMutable;
+ }
+
+ public SolrConfig getConfig() {
+ return config;
+ }
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaField.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaField.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaField.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaField.java Thu Mar 26 19:11:35 2015
@@ -104,6 +104,7 @@ public final class SchemaField extends F
public boolean sortMissingFirst() { return (properties & SORT_MISSING_FIRST)!=0; }
public boolean sortMissingLast() { return (properties & SORT_MISSING_LAST)!=0; }
public boolean isRequired() { return required; }
+ public Map<String,?> getArgs() { return Collections.unmodifiableMap(args); }
// things that should be determined by field type, not set as options
boolean isTokenized() { return (properties & TOKENIZED)!=0; }
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java Thu Mar 26 19:11:35 2015
@@ -21,7 +21,6 @@ package org.apache.solr.schema;
import org.apache.solr.cloud.ZkController;
import org.apache.solr.cloud.ZkSolrResourceLoader;
import org.apache.solr.common.SolrException;
-import org.apache.solr.core.ConfigOverlay;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
@@ -40,13 +39,12 @@ import java.io.StringWriter;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
-import java.util.HashSet;
+import java.util.HashMap;
import java.util.List;
-import java.util.Set;
+import java.util.Map;
import java.util.concurrent.TimeUnit;
-import static java.util.Collections.EMPTY_LIST;
-import static java.util.Collections.EMPTY_MAP;
+import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.solr.schema.FieldType.CLASS_NAME;
@@ -55,9 +53,10 @@ import static org.apache.solr.schema.Ind
import static org.apache.solr.schema.IndexSchema.SOURCE;
import static org.apache.solr.schema.IndexSchema.TYPE;
-/**A utility class to manipulate schema using the bulk mode.
- * This class takes in all the commands and process them completely. It is an all or none
- * operation
+/**
+ * A utility class to manipulate schema using the bulk mode.
+ * This class takes in all the commands and processes them completely.
+ * It is an all or nothing operation.
*/
public class SchemaManager {
private static final Logger log = LoggerFactory.getLogger(SchemaManager.class);
@@ -65,50 +64,35 @@ public class SchemaManager {
final SolrQueryRequest req;
ManagedIndexSchema managedIndexSchema;
- public static final String ADD_FIELD = "add-field";
- public static final String ADD_COPY_FIELD = "add-copy-field";
- public static final String ADD_DYNAMIC_FIELD = "add-dynamic-field";
- public static final String ADD_FIELD_TYPE = "add-field-type";
-
- private static final Set<String> KNOWN_OPS = new HashSet<>();
- static {
- KNOWN_OPS.add(ADD_COPY_FIELD);
- KNOWN_OPS.add(ADD_FIELD);
- KNOWN_OPS.add(ADD_DYNAMIC_FIELD);
- KNOWN_OPS.add(ADD_FIELD_TYPE);
- }
-
public SchemaManager(SolrQueryRequest req){
this.req = req;
-
}
- /**Take in a JSON command set and execute them . It tries to capture as many errors
- * as possible instead of failing at the frst error it encounters
- * @param rdr The input as a Reader
- * @return Lis of errors . If the List is empty then the operation is successful.
+ /**
+ * Take in a JSON command set and execute them. It tries to capture as many errors
+ * as possible instead of failing at the first error it encounters
+ * @param reader The input as a Reader
+ * @return List of errors. If the List is empty then the operation was successful.
*/
- public List performOperations(Reader rdr) throws Exception {
- List<CommandOperation> ops = null;
+ public List performOperations(Reader reader) throws Exception {
+ List<CommandOperation> ops;
try {
- ops = CommandOperation.parse(rdr);
+ ops = CommandOperation.parse(reader);
} catch (Exception e) {
- String msg= "Error parsing schema operations ";
- log.warn(msg ,e );
+ String msg = "Error parsing schema operations ";
+ log.warn(msg, e);
return Collections.singletonList(singletonMap(CommandOperation.ERR_MSGS, msg + ":" + e.getMessage()));
}
List errs = CommandOperation.captureErrors(ops);
- if(!errs.isEmpty()) return errs;
+ if (!errs.isEmpty()) return errs;
IndexSchema schema = req.getCore().getLatestSchema();
if (!(schema instanceof ManagedIndexSchema)) {
- return singletonList( singletonMap(CommandOperation.ERR_MSGS,"schema is not editable"));
+ return singletonList(singletonMap(CommandOperation.ERR_MSGS, "schema is not editable"));
}
-
synchronized (schema.getSchemaUpdateLock()) {
return doOperations(ops);
}
-
}
private List doOperations(List<CommandOperation> operations) throws InterruptedException, IOException, KeeperException {
@@ -116,16 +100,12 @@ public class SchemaManager {
long startTime = System.nanoTime();
long endTime = timeout > 0 ? System.nanoTime() + (timeout * 1000 * 1000) : Long.MAX_VALUE;
SolrCore core = req.getCore();
- for (; System.nanoTime() < endTime; ) {
+ while (System.nanoTime() < endTime) {
managedIndexSchema = getFreshManagedSchema();
for (CommandOperation op : operations) {
- if (ADD_FIELD.equals(op.name) || ADD_DYNAMIC_FIELD.equals(op.name)) {
- applyAddField(op);
- } else if(ADD_COPY_FIELD.equals(op.name)) {
- applyAddCopyField(op);
- } else if(ADD_FIELD_TYPE.equals(op.name)) {
- applyAddType(op);
-
+ OpType opType = OpType.get(op.name);
+ if (opType != null) {
+ opType.perform(op, this);
} else {
op.addError("No such operation : " + op.name);
}
@@ -150,28 +130,24 @@ public class SchemaManager {
managedIndexSchema.getResourceName(),
sw.toString().getBytes(StandardCharsets.UTF_8),
true);
- return EMPTY_LIST;
+ return Collections.emptyList();
} catch (ZkController.ResourceModifiedInZkException e) {
log.info("Race condition schema modified by another node");
- continue;
} catch (Exception e) {
String s = "Exception persisting schema";
log.warn(s, e);
return singletonList(s + e.getMessage());
}
-
- }else {
-
+ } else {
try {
//only for non cloud stuff
managedIndexSchema.persistManagedSchema(false);
core.setLatestSchema(managedIndexSchema);
waitForOtherReplicasToUpdate(timeout, startTime);
- return EMPTY_LIST;
+ return Collections.emptyList();
} catch (ManagedIndexSchema.SchemaChangedInZkException e) {
String s = "Failed to update schema because schema is modified";
log.warn(s, e);
- continue;
} catch (Exception e) {
String s = "Exception persisting schema";
log.warn(s, e);
@@ -179,120 +155,281 @@ public class SchemaManager {
}
}
}
-
return singletonList("Unable to persist schema");
-
}
private void waitForOtherReplicasToUpdate(int timeout, long startTime) {
- if(timeout > 0 && managedIndexSchema.getResourceLoader()instanceof ZkSolrResourceLoader){
+ if (timeout > 0 && managedIndexSchema.getResourceLoader() instanceof ZkSolrResourceLoader) {
CoreDescriptor cd = req.getCore().getCoreDescriptor();
String collection = cd.getCollectionName();
if (collection != null) {
ZkSolrResourceLoader zkLoader = (ZkSolrResourceLoader) managedIndexSchema.getResourceLoader();
- long timeLeftSecs = timeout - TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
- if(timeLeftSecs<=0) throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Not enough time left to update replicas. However the schema is updated already");
+ long timeLeftSecs = timeout - TimeUnit.SECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
+ if (timeLeftSecs <= 0) {
+ throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
+ "Not enough time left to update replicas. However, the schema is updated already.");
+ }
ManagedIndexSchema.waitForSchemaZkVersionAgreement(collection,
cd.getCloudDescriptor().getCoreNodeName(),
(managedIndexSchema).getSchemaZkVersion(),
zkLoader.getZkController(),
(int) timeLeftSecs);
}
-
}
}
- private boolean applyAddType(CommandOperation op) {
- String name = op.getStr(NAME);
- String clz = op.getStr(CLASS_NAME);
- if(op.hasError())
- return false;
- try {
- FieldType fieldType = managedIndexSchema.newFieldType(name, clz, op.getDataMap());
- managedIndexSchema = managedIndexSchema.addFieldTypes(singletonList(fieldType), false);
- return true;
- } catch (Exception e) {
- op.addError(getErrorStr(e));
- return false;
+ public enum OpType {
+ ADD_FIELD_TYPE("add-field-type") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String className = op.getStr(CLASS_NAME);
+ if (op.hasError())
+ return false;
+ try {
+ FieldType fieldType = mgr.managedIndexSchema.newFieldType(name, className, op.getDataMap());
+ mgr.managedIndexSchema = mgr.managedIndexSchema.addFieldTypes(singletonList(fieldType), false);
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ ADD_COPY_FIELD("add-copy-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String src = op.getStr(SOURCE);
+ Collection<String> dests = op.getStrs(DESTINATION);
+ if (op.hasError())
+ return false;
+ if ( ! op.getValuesExcluding(SOURCE, DESTINATION).isEmpty()) {
+ op.addError("Only the '" + SOURCE + "' and '" + DESTINATION
+ + "' params are allowed with the 'add-copy-field' operation");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.addCopyFields(singletonMap(src, dests), false);
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ ADD_FIELD("add-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String type = op.getStr(TYPE);
+ if (op.hasError())
+ return false;
+ FieldType ft = mgr.managedIndexSchema.getFieldTypeByName(type);
+ if (ft == null) {
+ op.addError("No such field type '" + type + "'");
+ return false;
+ }
+ try {
+ SchemaField field = SchemaField.create(name, ft, op.getValuesExcluding(NAME, TYPE));
+ mgr.managedIndexSchema
+ = mgr.managedIndexSchema.addFields(singletonList(field), Collections.EMPTY_MAP, false);
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ ADD_DYNAMIC_FIELD("add-dynamic-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String type = op.getStr(TYPE);
+ if (op.hasError())
+ return false;
+ FieldType ft = mgr.managedIndexSchema.getFieldTypeByName(type);
+ if (ft == null) {
+ op.addError("No such field type '" + type + "'");
+ return false;
+ }
+ try {
+ SchemaField field = SchemaField.create(name, ft, op.getValuesExcluding(NAME, TYPE));
+ mgr.managedIndexSchema
+ = mgr.managedIndexSchema.addDynamicFields(singletonList(field), Collections.EMPTY_MAP, false);
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ DELETE_FIELD_TYPE("delete-field-type") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ if (op.hasError())
+ return false;
+ if ( ! op.getValuesExcluding(NAME).isEmpty()) {
+ op.addError("Only the '" + NAME + "' param is allowed with the 'delete-field-type' operation");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.deleteFieldTypes(singleton(name));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ DELETE_COPY_FIELD("delete-copy-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String source = op.getStr(SOURCE);
+ Collection<String> dests = op.getStrs(DESTINATION);
+ if (op.hasError())
+ return false;
+ if ( ! op.getValuesExcluding(SOURCE, DESTINATION).isEmpty()) {
+ op.addError("Only the '" + SOURCE + "' and '" + DESTINATION
+ + "' params are allowed with the 'delete-copy-field' operation");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.deleteCopyFields(singletonMap(source, dests));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ DELETE_FIELD("delete-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ if (op.hasError())
+ return false;
+ if ( ! op.getValuesExcluding(NAME).isEmpty()) {
+ op.addError("Only the '" + NAME + "' param is allowed with the 'delete-field' operation");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.deleteFields(singleton(name));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ DELETE_DYNAMIC_FIELD("delete-dynamic-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ if (op.hasError())
+ return false;
+ if ( ! op.getValuesExcluding(NAME).isEmpty()) {
+ op.addError("Only the '" + NAME + "' param is allowed with the 'delete-dynamic-field' operation");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.deleteDynamicFields(singleton(name));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ REPLACE_FIELD_TYPE("replace-field-type") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String className = op.getStr(CLASS_NAME);
+ if (op.hasError())
+ return false;
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.replaceFieldType(name, className, op.getDataMap());
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ REPLACE_FIELD("replace-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String type = op.getStr(TYPE);
+ if (op.hasError())
+ return false;
+ FieldType ft = mgr.managedIndexSchema.getFieldTypeByName(type);
+ if (ft == null) {
+ op.addError("No such field type '" + type + "'");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.replaceField(name, ft, op.getValuesExcluding(NAME, TYPE));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ },
+ REPLACE_DYNAMIC_FIELD("replace-dynamic-field") {
+ @Override public boolean perform(CommandOperation op, SchemaManager mgr) {
+ String name = op.getStr(NAME);
+ String type = op.getStr(TYPE);
+ if (op.hasError())
+ return false;
+ FieldType ft = mgr.managedIndexSchema.getFieldTypeByName(type);
+ if (ft == null) {
+ op.addError("No such field type '" + type + "'");
+ return false;
+ }
+ try {
+ mgr.managedIndexSchema = mgr.managedIndexSchema.replaceDynamicField(name, ft, op.getValuesExcluding(NAME, TYPE));
+ return true;
+ } catch (Exception e) {
+ op.addError(getErrorStr(e));
+ return false;
+ }
+ }
+ };
+
+ public abstract boolean perform(CommandOperation op, SchemaManager mgr);
+
+ public static OpType get(String label) {
+ return Nested.OP_TYPES.get(label);
+ }
+
+ private static class Nested { // Initializes contained static map before any enum ctor
+ static final Map<String,OpType> OP_TYPES = new HashMap<>();
+ }
+
+ private OpType(String label) {
+ Nested.OP_TYPES.put(label, this);
}
}
public static String getErrorStr(Exception e) {
StringBuilder sb = new StringBuilder();
- Throwable cause= e;
- for(int i =0;i<5;i++) {
+ Throwable cause = e;
+ for (int i = 0 ; i < 5 ; i++) {
sb.append(cause.getMessage()).append("\n");
- if(cause.getCause() == null || cause.getCause() == cause) break;
+ if (cause.getCause() == null || cause.getCause() == cause) break;
cause = cause.getCause();
}
return sb.toString();
}
- private boolean applyAddCopyField(CommandOperation op) {
- String src = op.getStr(SOURCE);
- List<String> dest = op.getStrs(DESTINATION);
- if(op.hasError())
- return false;
- try {
- managedIndexSchema = managedIndexSchema.addCopyFields(Collections.<String,Collection<String>>singletonMap(src,dest), false);
- return true;
- } catch (Exception e) {
- op.addError(getErrorStr(e));
- return false;
- }
- }
-
-
- private boolean applyAddField( CommandOperation op) {
- String name = op.getStr(NAME);
- String type = op.getStr(TYPE);
- if(op.hasError())
- return false;
- FieldType ft = managedIndexSchema.getFieldTypeByName(type);
- if(ft==null){
- op.addError("No such field type '"+type+"'");
- return false;
- }
- try {
- if(ADD_DYNAMIC_FIELD.equals(op.name)){
- managedIndexSchema = managedIndexSchema.addDynamicFields(
- singletonList(SchemaField.create(name, ft, op.getValuesExcluding(NAME, TYPE))),
- EMPTY_MAP,false);
- } else {
- managedIndexSchema = managedIndexSchema.addFields(
- singletonList( SchemaField.create(name, ft, op.getValuesExcluding(NAME, TYPE))),
- EMPTY_MAP,
- false);
- }
- } catch (Exception e) {
- op.addError(getErrorStr(e));
- return false;
- }
- return true;
- }
-
public ManagedIndexSchema getFreshManagedSchema() throws IOException, KeeperException, InterruptedException {
SolrResourceLoader resourceLoader = req.getCore().getResourceLoader();
if (resourceLoader instanceof ZkSolrResourceLoader) {
- ZkSolrResourceLoader loader = (ZkSolrResourceLoader) resourceLoader;
InputStream in = resourceLoader.openResource(req.getSchema().getResourceName());
if (in instanceof ZkSolrResourceLoader.ZkByteArrayInputStream) {
int version = ((ZkSolrResourceLoader.ZkByteArrayInputStream) in).getStat().getVersion();
log.info("managed schema loaded . version : {} ", version);
- return new ManagedIndexSchema(req.getCore().getSolrConfig(),
- req.getSchema().getResourceName() ,new InputSource(in),
- true,
- req.getSchema().getResourceName(),
- version,new Object());
- }else {
+ return new ManagedIndexSchema
+ (req.getCore().getSolrConfig(), req.getSchema().getResourceName(), new InputSource(in),
+ true, req.getSchema().getResourceName(), version, req.getSchema().getSchemaUpdateLock());
+ } else {
return (ManagedIndexSchema) req.getCore().getLatestSchema();
}
-
} else {
return (ManagedIndexSchema) req.getCore().getLatestSchema();
}
-
-
-
}
}
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/ZkIndexSchemaReader.java Thu Mar 26 19:11:35 2015
@@ -103,10 +103,13 @@ public class ZkIndexSchemaReader impleme
if (expectedZkVersion == -1 || oldSchema.schemaZkVersion < expectedZkVersion) {
byte[] data = zkClient.getData(managedSchemaPath, watcher, stat, true);
if (stat.getVersion() != oldSchema.schemaZkVersion) {
- log.info("Retrieved schema version "+stat.getVersion()+" from ZooKeeper");
+ log.info("Retrieved schema version "+ stat.getVersion() + " from ZooKeeper");
long start = System.nanoTime();
InputSource inputSource = new InputSource(new ByteArrayInputStream(data));
- ManagedIndexSchema newSchema = oldSchema.reloadFields(inputSource, stat.getVersion());
+ String resourceName = managedIndexSchemaFactory.getManagedSchemaResourceName();
+ ManagedIndexSchema newSchema = new ManagedIndexSchema
+ (managedIndexSchemaFactory.getConfig(), resourceName, inputSource, managedIndexSchemaFactory.isMutable(),
+ resourceName, stat.getVersion(), oldSchema.getSchemaUpdateLock());
managedIndexSchemaFactory.setSchema(newSchema);
long stop = System.nanoTime();
log.info("Finished refreshing schema in " + TimeUnit.MILLISECONDS.convert(stop - start, TimeUnit.NANOSECONDS) + " ms");
Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java?rev=1669413&r1=1669412&r2=1669413&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/util/CommandOperation.java Thu Mar 26 19:11:35 2015
@@ -57,12 +57,13 @@ public class CommandOperation {
return o == null ? def : String.valueOf(o);
}
- public Map<String, Object> getDataMap() {
+ public Map<String,Object> getDataMap() {
if (commandData instanceof Map) {
- return (Map) commandData;
+ //noinspection unchecked
+ return (Map<String,Object>)commandData;
}
addError(StrUtils.formatString("The command ''{0}'' should have the values as a json object {key:val} format", name));
- return Collections.EMPTY_MAP;
+ return Collections.emptyMap();
}
private Object getRootPrimitive() {
@@ -163,10 +164,11 @@ public class CommandOperation {
* Get all the values from the metadata for the command
* without the specified keys
*/
- public Map getValuesExcluding(String... keys) {
+ public Map<String,Object> getValuesExcluding(String... keys) {
getMapVal(null);
if (hasError()) return emptyMap();//just to verify the type is Map
- LinkedHashMap<String, Object> cp = new LinkedHashMap<>((Map<String, Object>) commandData);
+ @SuppressWarnings("unchecked")
+ LinkedHashMap<String,Object> cp = new LinkedHashMap<>((Map<String,Object>)commandData);
if (keys == null) return cp;
for (String key : keys) {
cp.remove(key);