Index: solr/core/src/java/org/apache/solr/cloud/CreateAliasCmd.java IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== --- solr/core/src/java/org/apache/solr/cloud/CreateAliasCmd.java (revision cbae3fb15e748bafd3087397e8ee0a666425fa63) +++ solr/core/src/java/org/apache/solr/cloud/CreateAliasCmd.java (revision ) @@ -21,7 +21,9 @@ import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.stream.Collectors; +import org.apache.commons.lang3.StringUtils; import org.apache.solr.cloud.OverseerCollectionMessageHandler.Cmd; import org.apache.solr.common.SolrException; import org.apache.solr.common.cloud.ClusterState; @@ -44,12 +46,14 @@ public void call(ClusterState state, ZkNodeProps message, NamedList results) throws Exception { String aliasName = message.getStr(NAME); - String collections = message.getStr("collections"); // could be comma delimited list +// String collections = message.get("collections"); // could be comma delimited list + final List canonicalCollectionList = parseCollectionsParameter(message.get("collections")); + final String canonicalCollectionsString = StringUtils.join(canonicalCollectionList, ","); ZkStateReader zkStateReader = ocmh.zkStateReader; - validateAllCollectionsExistAndNoDups(collections, zkStateReader); + validateAllCollectionsExistAndNoDups(canonicalCollectionList, zkStateReader); - zkStateReader.aliasesHolder.applyModificationAndExportToZk(aliases -> aliases.cloneWithCollectionAlias(aliasName, collections)); + zkStateReader.aliasesHolder.applyModificationAndExportToZk(aliases -> aliases.cloneWithCollectionAlias(aliasName, canonicalCollectionsString)); // Sleep a bit to allow ZooKeeper state propagation. // @@ -66,20 +70,32 @@ Thread.sleep(100); } - private void validateAllCollectionsExistAndNoDups(String collections, ZkStateReader zkStateReader) { - List collectionArr = StrUtils.splitSmart(collections, ",", true); - if (new HashSet<>(collectionArr).size() != collectionArr.size()) { + private void validateAllCollectionsExistAndNoDups(List collectionList, ZkStateReader zkStateReader) { + final String collectionStr = StringUtils.join(collectionList, ","); + + if (new HashSet<>(collectionList).size() != collectionList.size()) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, - String.format(Locale.ROOT, "Can't create collection alias for collections='%s', since it contains duplicates", collections)); + String.format(Locale.ROOT, "Can't create collection alias for collections='%s', since it contains duplicates", collectionStr)); } ClusterState clusterState = zkStateReader.getClusterState(); Set aliasNames = zkStateReader.getAliases().getCollectionAliasListMap().keySet(); - for (String collection : collectionArr) { + for (String collection : collectionList) { if (clusterState.getCollectionOrNull(collection) == null && !aliasNames.contains(collection)) { throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, - String.format(Locale.ROOT, "Can't create collection alias for collections='%s', '%s' is not an existing collection or alias", collections, collection)); + String.format(Locale.ROOT, "Can't create collection alias for collections='%s', '%s' is not an existing collection or alias", collectionStr, collection)); } } } + + /** + * The v2 API directs that the 'collection' parameter be provided as a JSON array (e.g. ["a", "b"]). We also + * maintain support for the legacy format, a comma-separated list (e.g. a,b). + */ + private List parseCollectionsParameter(Object colls) { + if (colls instanceof List) return (List) colls; + return StrUtils.splitSmart(colls.toString(), ",", true).stream() + .map(coll -> coll.trim()) + .collect(Collectors.toList()); + } }