lucene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From no...@apache.org
Subject svn commit: r1629301 - in /lucene/dev/branches/branch_5x/solr/core/src: java/org/apache/solr/rest/schema/ java/org/apache/solr/schema/ test/org/apache/solr/rest/schema/ test/org/apache/solr/schema/
Date Fri, 03 Oct 2014 20:00:34 GMT
Author: noble
Date: Fri Oct  3 20:00:33 2014
New Revision: 1629301

URL: http://svn.apache.org/r1629301
Log:
SOLR-6476

Added:
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/schema/SchemaManager.java   (props changed)
      - copied unchanged from r1629271, lucene/dev/trunk/solr/core/src/java/org/apache/solr/schema/SchemaManager.java
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java   (with props)
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java   (with props)
    lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java   (with props)
Modified:
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java
    lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/SchemaResource.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

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/BaseFieldTypeResource.java Fri Oct  3 20:00:33 2014
@@ -70,7 +70,7 @@ abstract class BaseFieldTypeResource ext
     while (!success) {
       try {
         synchronized (oldSchema.getSchemaUpdateLock()) {
-          newSchema = oldSchema.addFieldTypes(newFieldTypes);
+          newSchema = oldSchema.addFieldTypes(newFieldTypes, true);
           getSolrCore().setLatestSchema(newSchema);
           success = true;
         }

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java Fri Oct  3 20:00:33 2014
@@ -173,7 +173,7 @@ public class CopyFieldCollectionResource
             while (!success) {
               try {
                 synchronized (oldSchema.getSchemaUpdateLock()) {
-                  newSchema = oldSchema.addCopyFields(fieldsToCopy);
+                  newSchema = oldSchema.addCopyFields(fieldsToCopy,true);
                   if (null != newSchema) {
                     getSolrCore().setLatestSchema(newSchema);
                     success = true;

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldCollectionResource.java Fri Oct  3 20:00:33 2014
@@ -178,7 +178,7 @@ public class DynamicFieldCollectionResou
                 }
                 firstAttempt = false;
                 synchronized (oldSchema.getSchemaUpdateLock()) {
-                  newSchema = oldSchema.addDynamicFields(newDynamicFields, copyFields);
+                  newSchema = oldSchema.addDynamicFields(newDynamicFields, copyFields, true);
                   if (null != newSchema) {
                     getSolrCore().setLatestSchema(newSchema);
                     success = true;

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/DynamicFieldResource.java Fri Oct  3 20:00:33 2014
@@ -32,9 +32,14 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.io.UnsupportedEncodingException;
+import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
+
+import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
 
 /**
  * This class responds to requests at /solr/(corename)/schema/dynamicfields/(pattern)
@@ -142,12 +147,12 @@ public class DynamicFieldResource extend
               } else {
                 ManagedIndexSchema oldSchema = (ManagedIndexSchema)getSchema();
                 Object copies = map.get(IndexSchema.COPY_FIELDS);
-                List<String> copyFieldNames = null;
+                Collection<String> copyFieldNames = null;
                 if (copies != null) {
                   if (copies instanceof List) {
                     copyFieldNames = (List<String>)copies;
                   } else if (copies instanceof String) {
-                    copyFieldNames = Collections.singletonList(copies.toString());
+                    copyFieldNames = singletonList(copies.toString());
                   } else {
                     String message = "Invalid '" + IndexSchema.COPY_FIELDS + "' type.";
                     log.error(message);
@@ -163,7 +168,7 @@ public class DynamicFieldResource extend
                   try {
                     SchemaField newDynamicField = oldSchema.newDynamicField(fieldNamePattern, fieldType, map);
                     synchronized (oldSchema.getSchemaUpdateLock()) {
-                      newSchema = oldSchema.addDynamicField(newDynamicField, copyFieldNames);
+                      newSchema = oldSchema.addDynamicFields(singletonList(newDynamicField), singletonMap(newDynamicField.getName(), copyFieldNames), true);
                       if (null != newSchema) {
                         getSolrCore().setLatestSchema(newSchema);
                         success = true;

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/FieldCollectionResource.java Fri Oct  3 20:00:33 2014
@@ -199,7 +199,7 @@ public class FieldCollectionResource ext
                 }
                 firstAttempt = false;
                 synchronized (oldSchema.getSchemaUpdateLock()) {
-                  newSchema = oldSchema.addFields(newFields, copyFields);
+                  newSchema = oldSchema.addFields(newFields, copyFields, true);
                   if (null != newSchema) {
                     getSolrCore().setLatestSchema(newSchema);
                     success = true;

Modified: lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/SchemaResource.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/SchemaResource.java?rev=1629301&r1=1629300&r2=1629301&view=diff
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/SchemaResource.java (original)
+++ lucene/dev/branches/branch_5x/solr/core/src/java/org/apache/solr/rest/schema/SchemaResource.java Fri Oct  3 20:00:33 2014
@@ -16,18 +16,26 @@ package org.apache.solr.rest.schema;
  * limitations under the License.
  */
 
+import org.apache.solr.request.SolrRequestInfo;
 import org.apache.solr.rest.BaseSolrResource;
 import org.apache.solr.rest.GETable;
+import org.apache.solr.rest.POSTable;
 import org.apache.solr.schema.IndexSchema;
+import org.apache.solr.schema.SchemaManager;
 import org.restlet.representation.Representation;
 import org.restlet.resource.ResourceException;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.Collections;
+import java.util.List;
+
 /**
  * This class responds to requests at /solr/(corename)/schema
  */
-public class SchemaResource extends BaseSolrResource implements GETable {
+public class SchemaResource extends BaseSolrResource implements GETable,POSTable {
   private static final Logger log = LoggerFactory.getLogger(SchemaResource.class);
 
   public SchemaResource() {
@@ -50,4 +58,25 @@ public class SchemaResource extends Base
 
     return new SolrOutputRepresentation();
   }
+
+  @Override
+  public Representation post(Representation representation) {
+    SolrRequestInfo requestInfo = SolrRequestInfo.getRequestInfo();
+    List<String> errs = null;
+    try {
+      String text = representation.getText();
+      errs = new SchemaManager(requestInfo.getReq()).performOperations(new StringReader(text));
+    } catch (IOException e) {
+      requestInfo.getRsp().add("errors", Collections.singletonList("Error reading input String " + e.getMessage()));
+      requestInfo.getRsp().setException(e);
+    }
+    if(!errs.isEmpty()){
+        requestInfo.getRsp().add("errors", errs);
+    }
+
+
+    return new BaseSolrResource.SolrOutputRepresentation();
+  }
+
+
 }

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=1629301&r1=1629300&r2=1629301&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 Fri Oct  3 20:00:33 2014
@@ -72,6 +72,9 @@ import java.util.TreeMap;
 import java.util.TreeSet;
 import java.util.regex.Pattern;
 
+import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
+
 /**
  * <code>IndexSchema</code> contains information about the valid fields in an index
  * and the types of those fields.
@@ -1471,23 +1474,26 @@ public class IndexSchema {
   }
 
   /**
-   * Copies this schema, adds the given field to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * Copies this schema, adds the given field to the copy
+   * Requires synchronizing on the object returned by
    * {@link #getSchemaUpdateLock()}.
    *
    * @param newField the SchemaField to add 
+   * @param persist to persist the schema or not 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 );
+  }
+
   public IndexSchema addField(SchemaField newField) {
-    String msg = "This IndexSchema is not mutable.";
-    log.error(msg);
-    throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+    return addField(newField, true);
   }
 
   /**
-   * Copies this schema, adds the given field to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * Copies this schema, adds the given field to the copy
+   *  Requires synchronizing on the object returned by
    * {@link #getSchemaUpdateLock()}.
    *
    * @param newField the SchemaField to add
@@ -1496,14 +1502,12 @@ public class IndexSchema {
    * @see #newField(String, String, Map)
    */
   public IndexSchema addField(SchemaField newField, Collection<String> copyFieldNames) {
-    String msg = "This IndexSchema is not mutable.";
-    log.error(msg);
-    throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+    return addFields(singletonList(newField), singletonMap(newField.getName(), copyFieldNames), true);
   }
 
   /**
-   * Copies this schema, adds the given fields to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * Copies this schema, adds the given fields to the copy
+   * Requires synchronizing on the object returned by
    * {@link #getSchemaUpdateLock()}.
    *
    * @param newFields the SchemaFields to add
@@ -1511,99 +1515,57 @@ public class IndexSchema {
    * @see #newField(String, String, Map)
    */
   public IndexSchema addFields(Collection<SchemaField> newFields) {
-    String msg = "This IndexSchema is not mutable.";
-    log.error(msg);
-    throw new SolrException(ErrorCode.SERVER_ERROR, msg);
+    return addFields(newFields, Collections.<String, Collection<String>>emptyMap(), true);
   }
 
   /**
-   * Copies this schema, adds the given fields to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * Copies this schema, adds the given fields to the copy.
+   * Requires synchronizing on the object returned by
    * {@link #getSchemaUpdateLock()}.
    *
    * @param newFields 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 Persist the schema or not
    * @return a new IndexSchema based on this schema with newFields added
    * @see #newField(String, String, Map)
    */
-  public IndexSchema addFields(Collection<SchemaField> newFields, Map<String, Collection<String>> copyFieldNames) {
+  public IndexSchema addFields(Collection<SchemaField> newFields, Map<String, Collection<String>> copyFieldNames, boolean persist) {
     String msg = "This IndexSchema is not mutable.";
     log.error(msg);
     throw new SolrException(ErrorCode.SERVER_ERROR, msg);
   }
 
-  /**
-   * Copies this schema, adds the given dynamic field to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
-   * {@link #getSchemaUpdateLock()}.
-   *
-   * @param newDynamicField the SchemaField to add 
-   * @return a new IndexSchema based on this schema with newField added
-   * @see #newDynamicField(String, String, Map)
-   */
-  public IndexSchema addDynamicField(SchemaField newDynamicField) {
-    String msg = "This IndexSchema is not mutable.";
-    log.error(msg);
-    throw new SolrException(ErrorCode.SERVER_ERROR, msg);
-  }
 
   /**
-   * Copies this schema, adds the given dynamic field to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
-   * {@link #getSchemaUpdateLock()}.
-   *
-   * @param newDynamicField the SchemaField to add
-   * @param copyFieldNames 0 or more names of targets to copy this field to.  The targets must already exist.
-   * @return a new IndexSchema based on this schema with newDynamicField added
-   * @see #newDynamicField(String, String, Map)
-   */
-  public IndexSchema addDynamicField(SchemaField newDynamicField, Collection<String> copyFieldNames) {
-    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, then persists the
-   * new schema.  Requires synchronizing on the object returned by
-   * {@link #getSchemaUpdateLock()}.
-   *
-   * @param newDynamicFields the SchemaFields to add
-   * @return a new IndexSchema based on this schema with newDynamicFields added
-   * @see #newDynamicField(String, String, Map)
-   */
-  public IndexSchema addDynamicFields(Collection<SchemaField> newDynamicFields) {
-    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, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * 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
    * @return a new IndexSchema based on this schema with newDynamicFields added
    * @see #newDynamicField(String, String, Map)
    */
   public IndexSchema addDynamicFields
-      (Collection<SchemaField> newDynamicFields, Map<String, Collection<String>> copyFieldNames) {
+      (Collection<SchemaField> newDynamicFields,
+       Map<String, Collection<String>> copyFieldNames,
+       boolean persist) {
     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, then
-   * persists the new schema.  Requires synchronizing on the object returned by
+   * 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 or not
    * @return The new Schema with the copy fields added
    */
-  public IndexSchema addCopyFields(Map<String, Collection<String>> copyFields){
+  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);
@@ -1673,15 +1635,16 @@ public class IndexSchema {
   }
 
   /**
-   * Copies this schema, adds the given field type to the copy, then persists the
-   * new schema.  Requires synchronizing on the object returned by
+   * Copies this schema, adds the given field type to the copy,
+   * Requires synchronizing on the object returned by
    * {@link #getSchemaUpdateLock()}.
    *
    * @param fieldTypeList a list of FieldTypes to add
+   * @param persist to persist the schema or not or not
    * @return a new IndexSchema based on this schema with the new types added
    * @see #newFieldType(String, String, Map)
    */
-  public IndexSchema addFieldTypes(List<FieldType> fieldTypeList) {
+  public IndexSchema addFieldTypes(List<FieldType> fieldTypeList, boolean persist) {
     String msg = "This IndexSchema is not mutable.";
     log.error(msg);
     throw new SolrException(ErrorCode.SERVER_ERROR, msg);
@@ -1690,13 +1653,13 @@ public class IndexSchema {
   /**
    * Returns a FieldType if the given typeName does not already
    * exist in this schema. The resulting FieldType can be used in a call
-   * to {@link #addFieldType(FieldType)}.
+   * to {@link #addFieldTypes(java.util.List, boolean)}.
    *
    * @param typeName the name of the type to add
    * @param className the name of the FieldType class
    * @param options the options to use when creating the FieldType
    * @return The created FieldType
-   * @see #addFieldType(FieldType)
+   * @see #addFieldTypes(java.util.List, boolean)
    */
   public FieldType newFieldType(String typeName, String className, Map<String,?> options) {
     String msg = "This IndexSchema is not mutable.";

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=1629301&r1=1629300&r2=1629301&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 Fri Oct  3 20:00:33 2014
@@ -80,6 +80,9 @@ import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 
+import static java.util.Collections.singletonList;
+import static java.util.Collections.singletonMap;
+
 /** Solr-managed schema - non-user-editable, but can be mutable via internal and external REST API requests. */
 public final class ManagedIndexSchema extends IndexSchema {
 
@@ -386,23 +389,11 @@ public final class ManagedIndexSchema ex
     }
   }
   
-  @Override
-  public ManagedIndexSchema addField(SchemaField newField) {
-    return addFields(Arrays.asList(newField));
-  }
-
-  @Override
-  public ManagedIndexSchema addField(SchemaField newField, Collection<String> copyFieldNames) {
-    return addFields(Arrays.asList(newField), Collections.singletonMap(newField.getName(), copyFieldNames));
-  }
 
   @Override
-  public ManagedIndexSchema addFields(Collection<SchemaField> newFields) {
-    return addFields(newFields, Collections.<String, Collection<String>>emptyMap());
-  }
-
-  @Override
-  public ManagedIndexSchema addFields(Collection<SchemaField> newFields, Map<String, Collection<String>> copyFieldNames) {
+  public ManagedIndexSchema addFields(Collection<SchemaField> newFields,
+                                      Map<String, Collection<String>> copyFieldNames,
+                                      boolean persist) {
     ManagedIndexSchema newSchema = null;
     if (isMutable) {
       boolean success = false;
@@ -439,12 +430,15 @@ public final class ManagedIndexSchema ex
         aware.inform(newSchema);
       }
       newSchema.refreshAnalyzers();
-      success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
-      if (success) {
-        log.debug("Added field(s): {}", newFields);
-      } else {
-        log.error("Failed to add field(s): {}", newFields);
-        newSchema = null;
+
+      if(persist) {
+        success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
+        if (success) {
+          log.debug("Added field(s): {}", newFields);
+        } else {
+          log.error("Failed to add field(s): {}", newFields);
+          newSchema = null;
+        }
       }
     } else {
       String msg = "This ManagedIndexSchema is not mutable.";
@@ -454,25 +448,10 @@ public final class ManagedIndexSchema ex
     return newSchema;
   }
 
-  @Override
-  public IndexSchema addDynamicField(SchemaField newDynamicField) {
-    return addDynamicFields(Arrays.asList(newDynamicField));
-  }
-
-  @Override
-  public IndexSchema addDynamicField(SchemaField newDynamicField, Collection<String> copyFieldNames) {
-    return addDynamicFields(Arrays.asList(newDynamicField),
-        Collections.singletonMap(newDynamicField.getName(), copyFieldNames));
-  }
-
-  @Override
-  public ManagedIndexSchema addDynamicFields(Collection<SchemaField> newDynamicFields) {
-    return addDynamicFields(newDynamicFields, Collections.<String,Collection<String>>emptyMap());
-  }
 
   @Override
   public ManagedIndexSchema addDynamicFields(Collection<SchemaField> newDynamicFields, 
-                                             Map<String,Collection<String>> copyFieldNames) {
+                                             Map<String,Collection<String>> copyFieldNames, boolean persist) {
     ManagedIndexSchema newSchema = null;
     if (isMutable) {
       boolean success = false;
@@ -489,7 +468,7 @@ public final class ManagedIndexSchema ex
         }
         dFields.add(new DynamicField(newDynamicField));
         newSchema.dynamicFields = dynamicFieldListToSortedArray(dFields);
-        
+
         Collection<String> copyFields = copyFieldNames.get(newDynamicField.getName());
         if (copyFields != null) {
           for (String copyField : copyFields) {
@@ -503,11 +482,13 @@ public final class ManagedIndexSchema ex
         aware.inform(newSchema);
       }
       newSchema.refreshAnalyzers();
-      success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
-      if (success) {
-        log.debug("Added dynamic field(s): {}", newDynamicFields);
-      } else {
-        log.error("Failed to add dynamic field(s): {}", newDynamicFields);
+      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);
+        } else {
+          log.error("Failed to add dynamic field(s): {}", newDynamicFields);
+        }
       }
     } else {
       String msg = "This ManagedIndexSchema is not mutable.";
@@ -518,7 +499,7 @@ public final class ManagedIndexSchema ex
   }
 
   @Override
-  public ManagedIndexSchema addCopyFields(Map<String, Collection<String>> copyFields) {
+  public ManagedIndexSchema addCopyFields(Map<String, Collection<String>> copyFields, boolean persist) {
     ManagedIndexSchema newSchema = null;
     if (isMutable) {
       boolean success = false;
@@ -536,21 +517,19 @@ public final class ManagedIndexSchema ex
         aware.inform(newSchema);
       }
       newSchema.refreshAnalyzers();
-      success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
-      if (success) {
-        log.debug("Added copy fields for {} sources", copyFields.size());
-      } else {
-        log.error("Failed to add copy fields for {} sources", copyFields.size());
+      if(persist) {
+        success = newSchema.persistManagedSchema(false); // don't just create - update it if it already exists
+        if (success) {
+          log.debug("Added copy fields for {} sources", copyFields.size());
+        } else {
+          log.error("Failed to add copy fields for {} sources", copyFields.size());
+        }
       }
     }
     return newSchema;
   }
-  
-  public ManagedIndexSchema addFieldType(FieldType fieldType) {
-    return addFieldTypes(Collections.singletonList(fieldType));
-  }  
 
-  public ManagedIndexSchema addFieldTypes(List<FieldType> fieldTypeList) {
+  public ManagedIndexSchema addFieldTypes(List<FieldType> fieldTypeList, boolean persist) {
     if (!isMutable) {
       String msg = "This ManagedIndexSchema is not mutable.";
       log.error(msg);
@@ -611,24 +590,26 @@ public final class ManagedIndexSchema ex
     }
 
     newSchema.refreshAnalyzers();
-    
-    boolean success = newSchema.persistManagedSchema(false);
-    if (success) {
-      if (log.isDebugEnabled()) {
-        StringBuilder fieldTypeNames = new StringBuilder();
-        for (int i=0; i < fieldTypeList.size(); i++) {
-          if (i > 0) fieldTypeNames.append(", ");
-          fieldTypeNames.append(fieldTypeList.get(i).typeName);
+
+    if (persist) {
+      boolean success = newSchema.persistManagedSchema(false);
+      if (success) {
+        if (log.isDebugEnabled()) {
+          StringBuilder fieldTypeNames = new StringBuilder();
+          for (int i=0; i < fieldTypeList.size(); i++) {
+            if (i > 0) fieldTypeNames.append(", ");
+            fieldTypeNames.append(fieldTypeList.get(i).typeName);
+          }
+          log.debug("Added field types: {}", fieldTypeNames.toString());
         }
-        log.debug("Added field types: {}", fieldTypeNames.toString());
+      } else {
+        // this is unlikely to happen as most errors are handled as exceptions in the persist code
+        log.error("Failed to add field types: {}", fieldTypeList);
+        throw new SolrException(ErrorCode.SERVER_ERROR,
+            "Failed to persist updated schema due to underlying storage issue; check log for more details!");
       }
-    } else {
-      // this is unlikely to happen as most errors are handled as exceptions in the persist code
-      log.error("Failed to add field types: {}", fieldTypeList);
-      throw new SolrException(ErrorCode.SERVER_ERROR, 
-          "Failed to persist updated schema due to underlying storage issue; check log for more details!");
     }
-    
+
     return newSchema;
   }  
   
@@ -834,7 +815,7 @@ public final class ManagedIndexSchema ex
    *                                   are copied; otherwise, they are not.
    * @return A shallow copy of this schema
    */
-  private ManagedIndexSchema shallowCopy(boolean includeFieldDataStructures) {
+   ManagedIndexSchema shallowCopy(boolean includeFieldDataStructures) {
     ManagedIndexSchema newSchema = null;
     try {
       newSchema = new ManagedIndexSchema

Added: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java?rev=1629301&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java (added)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/rest/schema/TestBulkSchemaAPI.java Fri Oct  3 20:00:33 2014
@@ -0,0 +1,236 @@
+package org.apache.solr.rest.schema;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.commons.io.FileUtils;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.schema.SchemaManager;
+import org.apache.solr.util.RestTestBase;
+import org.apache.solr.util.RestTestHarness;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.junit.After;
+import org.junit.Before;
+import org.noggit.JSONParser;
+import org.noggit.ObjectBuilder;
+import org.restlet.ext.servlet.ServerServlet;
+
+import java.io.File;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+
+public class TestBulkSchemaAPI extends RestTestBase {
+
+  private static File tmpSolrHome;
+  private static File tmpConfDir;
+
+  private static final String collection = "collection1";
+  private static final String confDir = collection + "/conf";
+
+
+  @Before
+  public void before() throws Exception {
+    tmpSolrHome = createTempDir().toFile();
+    tmpConfDir = new File(tmpSolrHome, confDir);
+    FileUtils.copyDirectory(new File(TEST_HOME()), tmpSolrHome.getAbsoluteFile());
+
+    final SortedMap<ServletHolder,String> extraServlets = new TreeMap<>();
+    final ServletHolder solrRestApi = new ServletHolder("SolrSchemaRestApi", ServerServlet.class);
+    solrRestApi.setInitParameter("org.restlet.application", "org.apache.solr.rest.SolrSchemaRestApi");
+    extraServlets.put(solrRestApi, "/schema/*");  // '/schema/*' matches '/schema', '/schema/', and '/schema/whatever...'
+
+    System.setProperty("managed.schema.mutable", "true");
+    System.setProperty("enable.update.log", "false");
+
+    createJettyAndHarness(tmpSolrHome.getAbsolutePath(), "solrconfig-managed-schema.xml", "schema-rest.xml",
+        "/solr", true, extraServlets);
+  }
+
+  @After
+  public void after() throws Exception {
+    if (jetty != null) {
+      jetty.stop();
+      jetty = null;
+    }
+    server = null;
+    restTestHarness = null;
+  }
+
+  public void testMultipleAddFieldWithErrors() throws Exception {
+
+    String payload = SolrTestCaseJ4.json( "{\n" +
+        "    'add-field' : {\n" +
+        "                 'name':'a1',\n" +
+        "                 'type': 'string1',\n" +
+        "                 'stored':true,\n" +
+        "                 'indexed':false\n" +
+        "                 },\n" +
+        "    'add-field' : {\n" +
+        "                 'type': 'string',\n" +
+        "                 'stored':true,\n" +
+        "                 'indexed':true\n" +
+        "                 }\n" +
+        "   \n" +
+        "    }");
+
+    String response = restTestHarness.post("/schema?wt=json", payload);
+    Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+    List l = (List) map.get("errors");
+
+    List errorList = (List) ((Map) l.get(0)).get(SchemaManager.ERR_MSGS);
+    assertEquals(1, errorList.size());
+    assertTrue (((String)errorList.get(0)).contains("No such field type"));
+    errorList = (List) ((Map) l.get(1)).get(SchemaManager.ERR_MSGS);
+    assertEquals(1, errorList.size());
+    assertTrue (((String)errorList.get(0)).contains("is a required field"));
+
+  }
+
+
+  public void testMultipleCommands() throws Exception{
+    String payload = "{\n" +
+        "          'add-field' : {\n" +
+        "                       'name':'a1',\n" +
+        "                       'type': 'string',\n" +
+        "                       'stored':true,\n" +
+        "                       'indexed':false\n" +
+        "                       },\n" +
+        "          'add-field' : {\n" +
+        "                       'name':'a2',\n" +
+        "                       'type': 'string',\n" +
+        "                       'stored':true,\n" +
+        "                       'indexed':true\n" +
+        "                       },\n" +
+        "          'add-dynamic-field' : {\n" +
+        "                       'name' :'*_lol',\n" +
+        "                        'type':'string',\n" +
+        "                        'stored':true,\n" +
+        "                        'indexed':true\n" +
+        "                        },\n" +
+        "          'add-copy-field' : {\n" +
+        "                       'source' :'a1',\n" +
+        "                        'dest':['a2','hello_lol']\n" +
+        "                        },\n" +
+        "          'add-field-type' : {\n" +
+        "                       'name' :'mystr',\n" +
+        "                       'class' : 'solr.StrField',\n" +
+        "                        'sortMissingLast':'true'\n" +
+        "                        },\n" +
+        "          'add-field-type' : {" +
+        "                     'name' : 'myNewTxtField',\n" +
+        "                     'class':'solr.TextField','positionIncrementGap':'100',\n" +
+        "                     'analyzer' : {\n" +
+        "                                  'charFilters':[\n" +
+        "                                            {'class':'solr.PatternReplaceCharFilterFactory','replacement':'$1$1','pattern':'([a-zA-Z])\\\\\\\\1+'}\n" +
+        "                                         ],\n" +
+        "                     'tokenizer':{'class':'solr.WhitespaceTokenizerFactory'},\n" +
+        "                     'filters':[\n" +
+        "                             {'class':'solr.WordDelimiterFilterFactory','preserveOriginal':'0'},\n" +
+        "                             {'class':'solr.StopFilterFactory','words':'stopwords.txt','ignoreCase':'true'},\n" +
+        "                             {'class':'solr.LowerCaseFilterFactory'},\n" +
+        "                             {'class':'solr.ASCIIFoldingFilterFactory'},\n" +
+        "                             {'class':'solr.KStemFilterFactory'}\n" +
+        "                  ]\n" +
+        "                }\n" +
+        "              }"+
+        "          }";
+
+    RestTestHarness harness = restTestHarness;
+
+
+    String response = harness.post("/schema?wt=json", SolrTestCaseJ4.json( payload));
+
+    Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+    assertNull(response,  map.get("errors"));
+
+
+    Map m = getObj(harness, "a1", "fields");
+    assertNotNull("field a1 not created", m);
+
+    assertEquals("string", m.get("type"));
+    assertEquals(Boolean.TRUE, m.get("stored"));
+    assertEquals(Boolean.FALSE, m.get("indexed"));
+
+    m = getObj(harness,"a2", "fields");
+    assertNotNull("field a2 not created", m);
+
+    assertEquals("string", m.get("type"));
+    assertEquals(Boolean.TRUE, m.get("stored"));
+    assertEquals(Boolean.TRUE, m.get("indexed"));
+
+    m = getObj(harness,"*_lol", "dynamicFields");
+    assertNotNull("field *_lol not created",m );
+
+    assertEquals("string", m.get("type"));
+    assertEquals(Boolean.TRUE, m.get("stored"));
+    assertEquals(Boolean.TRUE, m.get("indexed"));
+
+    List l = getCopyFields(harness,"a1");
+    Set s =new HashSet();
+    assertEquals(2,l.size());
+    s.add(((Map) l.get(0)).get("dest"));
+    s.add(((Map) l.get(1)).get("dest"));
+    assertTrue(s.contains("hello_lol"));
+    assertTrue(s.contains("a2"));
+
+    m = getObj(harness,"mystr", "fieldTypes");
+    assertNotNull(m);
+    assertEquals("solr.StrField",m.get("class"));
+    assertEquals("true",String.valueOf(m.get("sortMissingLast")));
+
+    m = getObj(harness,"myNewTxtField", "fieldTypes");
+    assertNotNull(m);
+
+
+  }
+
+  public static Map getObj(RestTestHarness restHarness, String fld, String key) throws Exception {
+    Map map = getRespMap(restHarness);
+    List l = (List) ((Map)map.get("schema")).get(key);
+    for (Object o : l) {
+      Map m = (Map) o;
+      if(fld.equals(m.get("name"))) return m;
+    }
+    return null;
+  }
+
+  public static Map getRespMap(RestTestHarness restHarness) throws Exception {
+    String response = restHarness.query("/schema?wt=json");
+    return (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+  }
+
+  public static List getCopyFields(RestTestHarness harness, String src) throws Exception {
+    Map map = getRespMap(harness);
+    List l = (List) ((Map)map.get("schema")).get("copyFields");
+    List result = new ArrayList();
+    for (Object o : l) {
+      Map m = (Map) o;
+      if(src.equals(m.get("source"))) result.add(m);
+    }
+    return result;
+
+  }
+
+
+}

Added: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java?rev=1629301&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java (added)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestBulkSchemaConcurrent.java Fri Oct  3 20:00:33 2014
@@ -0,0 +1,194 @@
+package org.apache.solr.schema;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.SolrServer;
+import org.apache.solr.client.solrj.impl.HttpSolrServer;
+import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
+import org.apache.solr.common.cloud.ZkStateReader;
+import org.apache.solr.util.RESTfulServerProvider;
+import org.apache.solr.util.RestTestHarness;
+import org.noggit.JSONParser;
+import org.noggit.ObjectBuilder;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
+import static java.text.MessageFormat.format;
+import static org.apache.solr.rest.schema.TestBulkSchemaAPI.getCopyFields;
+import static org.apache.solr.rest.schema.TestBulkSchemaAPI.getObj;
+
+public class TestBulkSchemaConcurrent  extends AbstractFullDistribZkTestBase {
+  static final Logger log =  LoggerFactory.getLogger(TestBulkSchemaConcurrent.class);
+  private List<RestTestHarness> restTestHarnesses = new ArrayList<>();
+
+  private void setupHarnesses() {
+    for (final SolrServer client : clients) {
+      RestTestHarness harness = new RestTestHarness(new RESTfulServerProvider() {
+        @Override
+        public String getBaseURL() {
+          return ((HttpSolrServer)client).getBaseURL();
+        }
+      });
+      restTestHarnesses.add(harness);
+    }
+  }
+  @Override
+  public void doTest() throws Exception {
+
+    final int threadCount = 5;
+    setupHarnesses();
+    Thread[] threads = new Thread[threadCount];
+    final List<List> collectErrors = new ArrayList<>();
+
+
+    for(int i=0;i<threadCount;i++){
+      final int finalI = i;
+      threads[i] = new Thread(){
+        @Override
+        public void run() {
+          try {
+            ArrayList errs = new ArrayList();
+            collectErrors.add(errs);
+            invokeBulkCall(finalI,errs);
+          } catch (IOException e) {
+            e.printStackTrace();
+          } catch (Exception e) {
+            e.printStackTrace();
+          }
+
+        }
+      };
+
+      threads[i].start();
+    }
+
+    for (Thread thread : threads) thread.join();
+
+    boolean success = true;
+
+    for (List e : collectErrors) {
+      if(!e.isEmpty()){
+        success = false;
+        log.error(e.toString());
+      }
+
+    }
+
+    assertTrue(success);
+
+
+  }
+
+  private void invokeBulkCall(int seed, ArrayList<String> errs) throws Exception {
+    String payload = "{\n" +
+        "          'add-field' : {\n" +
+        "                       'name':'replaceFieldA',\n" +
+        "                       'type': 'string',\n" +
+        "                       'stored':true,\n" +
+        "                       'indexed':false\n" +
+        "                       },\n" +
+        "          'add-dynamic-field' : {\n" +
+        "                       'name' :'replaceDynamicField',\n" +
+        "                        'type':'string',\n" +
+        "                        'stored':true,\n" +
+        "                        'indexed':true\n" +
+        "                        },\n" +
+        "          'add-copy-field' : {\n" +
+        "                       'source' :'replaceFieldA',\n" +
+        "                        'dest':['replaceDynamicCopyFieldDest']\n" +
+        "                        },\n" +
+        "          'add-field-type' : {\n" +
+        "                       'name' :'myNewFieldTypeName',\n" +
+        "                       'class' : 'solr.StrField',\n" +
+        "                        'sortMissingLast':'true'\n" +
+        "                        }\n" +
+        "\n" +
+        " }";
+    String aField = "a" + seed;
+    String dynamicFldName = "*_lol" + seed;
+    String dynamicCopyFldDest = "hello_lol"+seed;
+    String newFieldTypeName = "mystr" + seed;
+
+
+    RestTestHarness publisher = restTestHarnesses.get(r.nextInt(restTestHarnesses.size()));
+    payload = payload.replace("replaceFieldA1", aField);
+
+    payload = payload.replace("replaceDynamicField", dynamicFldName);
+    payload = payload.replace("dynamicFieldLol","lol"+seed);
+
+    payload = payload.replace("replaceDynamicCopyFieldDest",dynamicCopyFldDest);
+    payload = payload.replace("myNewFieldTypeName", newFieldTypeName);
+    String response = publisher.post("/schema?wt=json", SolrTestCaseJ4.json(payload));
+    Map map = (Map) ObjectBuilder.getVal(new JSONParser(new StringReader(response)));
+    Object errors = map.get("errors");
+    if(errors!= null){
+      errs.add(new String(ZkStateReader.toJSON(errors), StandardCharsets.UTF_8));
+      return;
+    }
+
+    //get another node
+    RestTestHarness harness = restTestHarnesses.get(r.nextInt(restTestHarnesses.size()));
+    long startTime = System.nanoTime();
+    boolean success = false;
+    long maxTimeoutMillis = 100000;
+    Set<String> errmessages = new HashSet<>();
+    while ( ! success
+        && TimeUnit.MILLISECONDS.convert(System.nanoTime() - startTime, TimeUnit.NANOSECONDS) < maxTimeoutMillis) {
+      errmessages.clear();
+      Map m = getObj(harness, aField, "fields");
+      if(m== null) errmessages.add(format("field {0} not created", aField));
+
+      m = getObj(harness, dynamicFldName, "dynamicFields");
+      if(m== null) errmessages.add(format("dynamic field {0} not created", dynamicFldName));
+
+      List l = getCopyFields(harness, "a1");
+      if(!checkCopyField(l,aField,dynamicCopyFldDest))
+        errmessages.add(format("CopyField source={0},dest={1} not created" , aField,dynamicCopyFldDest));
+
+      m = getObj(harness, "mystr", "fieldTypes");
+      if(m == null) errmessages.add(format("new type {}  not created" , newFieldTypeName));
+      Thread.sleep(10);
+    }
+    if(!errmessages.isEmpty()){
+      errs.addAll(errmessages);
+    }
+  }
+
+  private boolean checkCopyField(List<Map> l, String src, String dest) {
+    if(l == null) return false;
+    for (Map map : l) {
+      if(src.equals(map.get("source")) &&
+          dest.equals(map.get("dest"))) return true;
+    }
+    return false;
+  }
+
+
+}

Added: lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java?rev=1629301&view=auto
==============================================================================
--- lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java (added)
+++ lucene/dev/branches/branch_5x/solr/core/src/test/org/apache/solr/schema/TestSchemaManager.java Fri Oct  3 20:00:33 2014
@@ -0,0 +1,77 @@
+package org.apache.solr.schema;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+public class TestSchemaManager extends SolrTestCaseJ4 {
+  @BeforeClass
+  public static void beforeClass() throws Exception {
+    initCore("solrconfig.xml","schema-tiny.xml");
+  }
+
+  @Test
+  public void testParsing() throws IOException {
+    String x = "{\n" +
+        " \"add-field\" : {\n" +
+        "              \"name\":\"a\",\n" +
+        "              \"type\": \"string\",\n" +
+        "              \"stored\":true,\n" +
+        "              \"indexed\":false\n" +
+        "              },\n" +
+        " \"add-field\" : {\n" +
+        "              \"name\":\"b\",\n" +
+        "              \"type\": \"string\",\n" +
+        "              \"stored\":true,\n" +
+        "              \"indexed\":false\n" +
+        "              }\n" +
+        "\n" +
+        "}";
+
+    List<SchemaManager.Operation> ops = SchemaManager.parse(new StringReader(x));
+    assertEquals(2,ops.size());
+    assertTrue( SchemaManager.captureErrors(ops).isEmpty());
+
+    x = " {\"add-field\" : [{\n" +
+        "                                 \"name\":\"a1\",\n" +
+        "                                 \"type\": \"string\",\n" +
+        "                                 \"stored\":true,\n" +
+        "                                 \"indexed\":false\n" +
+        "                                 },\n" +
+        "                            {\n" +
+        "                            \"name\":\"a2\",\n" +
+        "                             \"type\": \"string\",\n" +
+        "                             \"stored\":true,\n" +
+        "                             \"indexed\":true\n" +
+        "                             }]\n" +
+        "           }";
+    ops = SchemaManager.parse(new StringReader(x));
+    assertEquals(2,ops.size());
+    assertTrue( SchemaManager.captureErrors(ops).isEmpty());
+
+  }
+
+
+
+}



Mime
View raw message