diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 983661033de..f8dd4156979 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -159,6 +159,12 @@ Bug Fixes
* SOLR-6149: Specifying the query value without any index value does not work in
Analysis browser. (Aman Tandon, shalin)
+
+* SOLR-6145: Fix Schema API optimistic concurrency by moving it out of
+ ManagedIndexSchema.add(Copy)Fields() into the consumers of those methods:
+ CopyFieldCollectionResource, FieldCollectionResource, FieldResource,
+ and AddSchemaFieldsUpdateProcessorFactory.
+ (Gregory Chanan, Alexey Serba, Steve Rowe)
* SOLR-6146: Incorrect configuration such as wrong chroot in zk server address can
cause CloudSolrServer to leak resources. (Jessica Cheng, Varun Thacker, shalin)
diff --git a/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java b/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
index a90391ddb5d..25c284f1b88 100644
--- a/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
+++ b/solr/core/src/java/org/apache/solr/rest/schema/CopyFieldCollectionResource.java
@@ -30,7 +30,6 @@ import org.restlet.resource.ResourceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -40,6 +39,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
+import static org.apache.solr.common.SolrException.ErrorCode;
+
/**
* This class responds to requests at /solr/(corename)/schema/copyfields
*
@@ -110,13 +111,13 @@ public class CopyFieldCollectionResource extends BaseFieldResource implements GE
try {
if (!getSchema().isMutable()) {
final String message = "This IndexSchema is not mutable.";
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message);
+ throw new SolrException(ErrorCode.BAD_REQUEST, message);
} else {
if (!entity.getMediaType().equals(MediaType.APPLICATION_JSON, true)) {
String message = "Only media type " + MediaType.APPLICATION_JSON.toString() + " is accepted."
+ " Request has media type " + entity.getMediaType().toString() + ".";
log.error(message);
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message);
+ throw new SolrException(ErrorCode.BAD_REQUEST, message);
} else {
Object object = ObjectBuilder.fromJSON(entity.getText());
@@ -124,7 +125,7 @@ public class CopyFieldCollectionResource extends BaseFieldResource implements GE
String message = "Invalid JSON type " + object.getClass().getName() + ", expected List of the form"
+ " (ignore the backslashes): [{\"source\":\"foo\",\"dest\":\"comma-separated list of targets\"}, {...}, ...]";
log.error(message);
- throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, message);
+ throw new SolrException(ErrorCode.BAD_REQUEST, message);
} else {
List