This is an automated email from the ASF dual-hosted git repository.

gerlowskija pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/solr.git


The following commit(s) were added to refs/heads/main by this push:
     new df88d65  SOLR-15745: Move public v2 "core-admin" APIs to annotation 
framework (#565)
df88d65 is described below

commit df88d65a2a83833116db355b722f91771949bef6
Author: Jason Gerlowski <[email protected]>
AuthorDate: Thu Jan 27 06:41:16 2022 -0500

    SOLR-15745: Move public v2 "core-admin" APIs to annotation framework (#565)
    
    Solr's been in the slow process of moving its v2 APIs away from the
    existing apispec/mapping framework towards one that relies on more
    explicit annotations to specify API properties.
    
    This commit converts the 'reload', 'swap', 'rename', 'unload',
    'merge-indexes', and 'split' commands of `/v2/cores/<core>` over to the
    preferred framework.
    
    (NOTE: the spelling 'indexes' in the 'merge-indexes' command was
    retained here for consistency/compatibility.  We should consider
    changing it going forward.)
---
 .../java/org/apache/solr/handler/ClusterAPI.java   |  26 +--
 .../solr/handler/admin/CoreAdminHandler.java       |  12 ++
 .../solr/handler/admin/api/MergeIndexesAPI.java    |  91 +++++++++
 .../solr/handler/admin/api/ReloadCoreAPI.java      |  69 +++++++
 .../solr/handler/admin/api/RenameCoreAPI.java      |  72 ++++++++
 .../solr/handler/admin/api/SplitCoreAPI.java       | 103 +++++++++++
 .../solr/handler/admin/api/SwapCoresAPI.java       |  77 ++++++++
 .../solr/handler/admin/api/UnloadCoreAPI.java      |  78 ++++++++
 .../handler/admin/api/V2CoreAPIMappingTest.java    | 203 +++++++++++++++++++++
 .../solr/client/solrj/request/CoreApiMapping.java  |   6 -
 .../src/resources/apispec/cores.core.Commands.json |  93 ----------
 .../apispec/cores.core.Commands.split.json         |  34 ----
 .../apache/solr/common/util/JsonValidatorTest.java |  27 +--
 13 files changed, 721 insertions(+), 170 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java 
b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
index a40acc0..42f5082 100644
--- a/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
+++ b/solr/core/src/java/org/apache/solr/handler/ClusterAPI.java
@@ -17,9 +17,6 @@
 
 package org.apache.solr.handler;
 
-import java.io.IOException;
-import java.util.*;
-
 import com.google.common.collect.Maps;
 import org.apache.solr.api.Command;
 import org.apache.solr.api.EndPoint;
@@ -48,18 +45,21 @@ import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.response.SolrQueryResponse;
 import org.apache.zookeeper.KeeperException;
 
+import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.NoSuchElementException;
+import java.util.Set;
+
 import static org.apache.solr.client.solrj.SolrRequest.METHOD.DELETE;
-import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
-import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
-import static org.apache.solr.client.solrj.SolrRequest.METHOD.PUT;
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.*;
 import static 
org.apache.solr.cloud.api.collections.CollectionHandlingUtils.REQUESTID;
 import static org.apache.solr.common.params.CollectionParams.ACTION;
 import static 
org.apache.solr.common.params.CollectionParams.CollectionAction.*;
 import static org.apache.solr.core.RateLimiterConfig.RL_CONFIG_KEY;
-import static 
org.apache.solr.security.PermissionNameProvider.Name.COLL_EDIT_PERM;
-import static 
org.apache.solr.security.PermissionNameProvider.Name.COLL_READ_PERM;
-import static 
org.apache.solr.security.PermissionNameProvider.Name.CONFIG_EDIT_PERM;
-import static 
org.apache.solr.security.PermissionNameProvider.Name.CONFIG_READ_PERM;
+import static org.apache.solr.security.PermissionNameProvider.Name.*;
 
 /**
  * All V2 APIs that have  a prefix of /api/cluster/
@@ -293,7 +293,11 @@ public class ClusterAPI {
     ModifiableSolrParams solrParams = new ModifiableSolrParams();
     m.forEach((k, v) -> {
       if (v == null) return;
-      solrParams.add(k.toString(), String.valueOf(v));
+      if (v instanceof String[]) {
+        solrParams.add(k, (String[]) v);
+      } else {
+        solrParams.add(k, String.valueOf(v));
+      }
     });
     DefaultSolrParams dsp = new DefaultSolrParams(req.getParams(), solrParams);
     req.setParams(dsp);
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java 
b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
index 52b2944..27e6116 100644
--- a/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
+++ b/solr/core/src/java/org/apache/solr/handler/admin/CoreAdminHandler.java
@@ -39,9 +39,15 @@ import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.handler.admin.api.AllCoresStatusAPI;
 import org.apache.solr.handler.admin.api.CreateCoreAPI;
 import org.apache.solr.handler.admin.api.InvokeClassAPI;
+import org.apache.solr.handler.admin.api.MergeIndexesAPI;
 import org.apache.solr.handler.admin.api.OverseerOperationAPI;
 import org.apache.solr.handler.admin.api.RejoinLeaderElectionAPI;
+import org.apache.solr.handler.admin.api.ReloadCoreAPI;
+import org.apache.solr.handler.admin.api.RenameCoreAPI;
 import org.apache.solr.handler.admin.api.SingleCoreStatusAPI;
+import org.apache.solr.handler.admin.api.SplitCoreAPI;
+import org.apache.solr.handler.admin.api.SwapCoresAPI;
+import org.apache.solr.handler.admin.api.UnloadCoreAPI;
 import org.apache.solr.logging.MDCLoggingContext;
 import org.apache.solr.metrics.SolrMetricManager;
 import org.apache.solr.metrics.SolrMetricsContext;
@@ -429,6 +435,12 @@ public class CoreAdminHandler extends RequestHandlerBase 
implements PermissionNa
     apis.addAll(AnnotatedApi.getApis(new InvokeClassAPI(this)));
     apis.addAll(AnnotatedApi.getApis(new RejoinLeaderElectionAPI(this)));
     apis.addAll(AnnotatedApi.getApis(new OverseerOperationAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new ReloadCoreAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new SwapCoresAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new RenameCoreAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new UnloadCoreAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new MergeIndexesAPI(this)));
+    apis.addAll(AnnotatedApi.getApis(new SplitCoreAPI(this)));
     return apis;
   }
 
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/MergeIndexesAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/MergeIndexesAPI.java
new file mode 100644
index 0000000..21e7787
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/MergeIndexesAPI.java
@@ -0,0 +1,91 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.params.UpdateParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for merging one or more Solr cores into the target core.
+ *
+ * The new API (POST /v2/cores/coreName {'merge-indexes': {...}}) is 
equivalent to the v1
+ * /admin/cores?action=mergeindexes command.
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class MergeIndexesAPI {
+    private static final String V2_MERGE_INDEXES_CORE_CMD = "merge-indexes";
+
+    private final CoreAdminHandler coreHandler;
+
+    public MergeIndexesAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_MERGE_INDEXES_CORE_CMD)
+    public void mergeIndexesIntoCore(PayloadObj<MergeIndexesPayload> obj) 
throws Exception {
+        final MergeIndexesPayload v2Body = obj.get();
+        final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
+        v1Params.put(CoreAdminParams.ACTION, 
CoreAdminParams.CoreAdminAction.MERGEINDEXES.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
+        if (! CollectionUtils.isEmpty(v2Body.indexDir)) {
+            v1Params.put("indexDir", v2Body.indexDir.toArray(new 
String[v2Body.indexDir.size()]));
+        }
+        if (! CollectionUtils.isEmpty(v2Body.srcCore)) {
+            v1Params.put("srcCore", v2Body.srcCore.toArray(new 
String[v2Body.srcCore.size()]));
+        }
+        // V1 API uses 'update.chain' instead of 'updateChain'.
+        if (v2Body.updateChain != null) {
+            v1Params.put(UpdateParams.UPDATE_CHAIN, 
v1Params.remove("updateChain"));
+        }
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class MergeIndexesPayload implements ReflectMapWriter {
+        @JsonProperty
+        public List<String> indexDir;
+
+        @JsonProperty
+        public List<String> srcCore;
+
+        @JsonProperty
+        public String updateChain;
+
+        @JsonProperty
+        public String async;
+    }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCoreAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCoreAPI.java
new file mode 100644
index 0000000..2ee076a
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/ReloadCoreAPI.java
@@ -0,0 +1,69 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.common.params.CommonParams.ACTION;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for reloading an individual core.
+ *
+ * The new API (POST /v2/cores/coreName {'reload': {...}}) is equivalent to 
the v1
+ * /admin/cores?action=reload command.
+ *
+ * @see ReloadCorePayload
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class ReloadCoreAPI {
+    private static final String V2_RELOAD_CORE_CMD = "reload";
+
+    private final CoreAdminHandler coreHandler;
+
+    public ReloadCoreAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_RELOAD_CORE_CMD)
+    public void reloadCore(PayloadObj<ReloadCorePayload> obj) throws Exception 
{
+        final String coreName = 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE);
+
+        final Map<String, Object> v1Params = new HashMap<>();
+        v1Params.put(ACTION, 
CoreAdminParams.CoreAdminAction.RELOAD.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, coreName);
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class ReloadCorePayload implements ReflectMapWriter {}
+}
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java
new file mode 100644
index 0000000..8782792
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/RenameCoreAPI.java
@@ -0,0 +1,72 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for renaming an existing Solr core.
+ *
+ * The new API (POST /v2/cores/coreName {'rename': {...}}) is equivalent to 
the v1
+ * /admin/cores?action=rename command.
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class RenameCoreAPI {
+    private static final String V2_RENAME_CORE_CMD = "rename";
+
+    private final CoreAdminHandler coreHandler;
+
+    public RenameCoreAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_RENAME_CORE_CMD)
+    public void renameCore(PayloadObj<RenameCorePayload> obj) throws Exception 
{
+        final RenameCorePayload v2Body = obj.get();
+        final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
+        v1Params.put(CoreAdminParams.ACTION, 
CoreAdminParams.CoreAdminAction.RENAME.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
+
+        // V1 API uses 'other' instead of 'to' to represent the new core name.
+        v1Params.put(CoreAdminParams.OTHER, v1Params.remove("to"));
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class RenameCorePayload implements ReflectMapWriter {
+        @JsonProperty(required = true)
+        public String to;
+    }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java
new file mode 100644
index 0000000..6f9404a
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/SplitCoreAPI.java
@@ -0,0 +1,103 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.common.params.CommonAdminParams.SPLIT_KEY;
+import static org.apache.solr.common.params.CommonParams.PATH;
+import static org.apache.solr.common.params.CoreAdminParams.TARGET_CORE;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for splitting a single core into multiple pieces
+ *
+ * The new API (POST /v2/cores/coreName {'split': {...}}) is equivalent to the 
v1
+ * /admin/cores?action=split command.
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class SplitCoreAPI {
+    private static final String V2_SPLIT_CORE_CMD = "split";
+
+    private final CoreAdminHandler coreHandler;
+
+    public SplitCoreAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_SPLIT_CORE_CMD)
+    public void splitCore(PayloadObj<SplitCorePayload> obj) throws Exception {
+        final SplitCorePayload v2Body = obj.get();
+        final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
+        v1Params.put(CoreAdminParams.ACTION, 
CoreAdminParams.CoreAdminAction.SPLIT.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
+
+        if (! CollectionUtils.isEmpty(v2Body.path)) {
+            v1Params.put(PATH, v2Body.path.toArray(new 
String[v2Body.path.size()]));
+        }
+        if (! CollectionUtils.isEmpty(v2Body.targetCore)) {
+            v1Params.put(TARGET_CORE, v2Body.targetCore.toArray(new 
String[v2Body.targetCore.size()]));
+        }
+
+        if (v2Body.splitKey != null) {
+            v1Params.put(SPLIT_KEY, v1Params.remove("splitKey"));
+        }
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class SplitCorePayload implements ReflectMapWriter {
+        @JsonProperty
+        public List<String> path;
+
+        @JsonProperty
+        public List<String> targetCore;
+
+        @JsonProperty
+        public String splitKey;
+
+        @JsonProperty
+        public String splitMethod;
+
+        @JsonProperty
+        public Boolean getRanges;
+
+        @JsonProperty
+        public String ranges;
+
+        @JsonProperty
+        public String async;
+    }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/SwapCoresAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/SwapCoresAPI.java
new file mode 100644
index 0000000..77a0a0b
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/SwapCoresAPI.java
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for swapping two existing Solr cores.
+ *
+ * Not intended for use in SolrCloud mode.
+ *
+ * The new API (POST /v2/cores/coreName {'swap': {...}}) is equivalent to the 
v1
+ * /admin/cores?action=swap command.
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class SwapCoresAPI {
+    private static final String V2_SWAP_CORES_CMD = "swap";
+
+    private final CoreAdminHandler coreHandler;
+
+    public SwapCoresAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_SWAP_CORES_CMD)
+    public void swapCores(PayloadObj<SwapCoresPayload> obj) throws Exception {
+        final SwapCoresPayload v2Body = obj.get();
+        final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
+        v1Params.put(CoreAdminParams.ACTION, 
CoreAdminParams.CoreAdminAction.SWAP.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
+
+        // V1 API uses 'other' instead of 'with' to represent the 
second/replacement core.
+        v1Params.put(CoreAdminParams.OTHER, v1Params.remove("with"));
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class SwapCoresPayload implements ReflectMapWriter {
+        @JsonProperty(required = true)
+        public String with;
+
+        @JsonProperty
+        public String async;
+    }
+}
diff --git 
a/solr/core/src/java/org/apache/solr/handler/admin/api/UnloadCoreAPI.java 
b/solr/core/src/java/org/apache/solr/handler/admin/api/UnloadCoreAPI.java
new file mode 100644
index 0000000..91f6e06
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/handler/admin/api/UnloadCoreAPI.java
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import org.apache.solr.api.Command;
+import org.apache.solr.api.EndPoint;
+import org.apache.solr.api.PayloadObj;
+import org.apache.solr.common.annotation.JsonProperty;
+import org.apache.solr.common.params.CoreAdminParams;
+import org.apache.solr.common.util.ReflectMapWriter;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+
+import static org.apache.solr.client.solrj.SolrRequest.METHOD.POST;
+import static org.apache.solr.handler.ClusterAPI.wrapParams;
+import static 
org.apache.solr.security.PermissionNameProvider.Name.CORE_EDIT_PERM;
+
+/**
+ * V2 API for renaming an existing Solr core.
+ *
+ * The new API (POST /v2/cores/coreName {'unload': {...}}) is equivalent to 
the v1
+ * /admin/cores?action=unload command.
+ */
+@EndPoint(
+        path = {"/cores/{core}"},
+        method = POST,
+        permission = CORE_EDIT_PERM)
+public class UnloadCoreAPI {
+    private static final String V2_UNLOAD_CORE_CMD = "unload";
+
+    private final CoreAdminHandler coreHandler;
+
+    public UnloadCoreAPI(CoreAdminHandler coreHandler) {
+        this.coreHandler = coreHandler;
+    }
+
+    @Command(name = V2_UNLOAD_CORE_CMD)
+    public void unloadCore(PayloadObj<UnloadCorePayload> obj) throws Exception 
{
+        final UnloadCorePayload v2Body = obj.get();
+        final Map<String, Object> v1Params = v2Body.toMap(new HashMap<>());
+        v1Params.put(CoreAdminParams.ACTION, 
CoreAdminParams.CoreAdminAction.UNLOAD.name().toLowerCase(Locale.ROOT));
+        v1Params.put(CoreAdminParams.CORE, 
obj.getRequest().getPathTemplateValues().get(CoreAdminParams.CORE));
+
+        coreHandler.handleRequestBody(wrapParams(obj.getRequest(), v1Params), 
obj.getResponse());
+    }
+
+    public static class UnloadCorePayload implements ReflectMapWriter {
+        @JsonProperty
+        public Boolean deleteIndex;
+
+        @JsonProperty
+        public Boolean deleteDataDir;
+
+        @JsonProperty
+        public Boolean deleteInstanceDir;
+
+        @JsonProperty
+        public String async;
+    }
+}
diff --git 
a/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
 
b/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
new file mode 100644
index 0000000..7dbd3f7
--- /dev/null
+++ 
b/solr/core/src/test/org/apache/solr/handler/admin/api/V2CoreAPIMappingTest.java
@@ -0,0 +1,203 @@
+/*
+ * 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.
+ */
+
+package org.apache.solr.handler.admin.api;
+
+import com.google.common.collect.Maps;
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.api.Api;
+import org.apache.solr.api.ApiBag;
+import org.apache.solr.common.params.SolrParams;
+import org.apache.solr.common.params.UpdateParams;
+import org.apache.solr.common.util.CommandOperation;
+import org.apache.solr.common.util.ContentStreamBase;
+import org.apache.solr.handler.admin.CoreAdminHandler;
+import org.apache.solr.request.LocalSolrQueryRequest;
+import org.apache.solr.request.SolrQueryRequest;
+import org.apache.solr.response.SolrQueryResponse;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.apache.solr.common.params.CommonAdminParams.ASYNC;
+import static org.apache.solr.common.params.CommonAdminParams.SPLIT_KEY;
+import static org.apache.solr.common.params.CommonParams.ACTION;
+import static org.apache.solr.common.params.CommonParams.PATH;
+import static org.apache.solr.common.params.CoreAdminParams.*;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+/**
+ * Unit tests for the V2 APIs found in {@link 
org.apache.solr.handler.admin.api} that use the /cores/{core} path.
+ *
+ * Note that the V2 requests made by these tests are not necessarily 
semantically valid.  They shouldn't be taken as
+ * examples. In several instances, mutually exclusive JSON parameters are 
provided.  This is done to exercise conversion
+ * of all parameters, even if particular combinations are never expected in 
the same request.
+ */
+public class V2CoreAPIMappingTest extends SolrTestCaseJ4 {
+    private ApiBag apiBag;
+
+    private ArgumentCaptor<SolrQueryRequest> queryRequestCaptor;
+
+    private CoreAdminHandler mockCoreHandler;
+
+    @BeforeClass
+    public static void ensureWorkingMockito() {
+        assumeWorkingMockito();
+    }
+
+    @Before
+    public void setupApiBag() throws Exception {
+        mockCoreHandler = mock(CoreAdminHandler.class);
+        queryRequestCaptor = ArgumentCaptor.forClass(SolrQueryRequest.class);
+
+        apiBag = new ApiBag(false);
+        apiBag.registerObject(new ReloadCoreAPI(mockCoreHandler));
+        apiBag.registerObject(new SwapCoresAPI(mockCoreHandler));
+        apiBag.registerObject(new RenameCoreAPI(mockCoreHandler));
+        apiBag.registerObject(new UnloadCoreAPI(mockCoreHandler));
+        apiBag.registerObject(new MergeIndexesAPI(mockCoreHandler));
+        apiBag.registerObject(new SplitCoreAPI(mockCoreHandler));
+    }
+
+    @Test
+    public void testReloadCoreAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST", "{\"reload\": {}}");
+
+        assertEquals("reload", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+    }
+
+    @Test
+    public void testSwapCoresAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST", "{\"swap\": {\"with\": 
\"otherCore\"}}");
+
+        assertEquals("swap", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+        assertEquals("otherCore", v1Params.get(OTHER));
+    }
+
+    @Test
+    public void testRenameCoreAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST", "{\"rename\": {\"to\": 
\"otherCore\"}}");
+
+        assertEquals("rename", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+        assertEquals("otherCore", v1Params.get(OTHER));
+    }
+
+    @Test
+    public void testUnloadCoreAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST",
+                "{" +
+                "\"unload\": {" +
+                        "\"deleteIndex\": true, " +
+                        "\"deleteDataDir\": true, " +
+                        "\"deleteInstanceDir\": true, " +
+                        "\"async\": \"someRequestId\"}}");
+
+        assertEquals("unload", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+        assertEquals(true, v1Params.getBool(DELETE_INDEX));
+        assertEquals(true, v1Params.getBool(DELETE_DATA_DIR));
+        assertEquals(true, v1Params.getBool(DELETE_INSTANCE_DIR));
+        assertEquals("someRequestId", v1Params.get(ASYNC));
+    }
+
+    @Test
+    public void testMergeIndexesAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST",
+                "{" +
+                        "\"merge-indexes\": {" +
+                          "\"indexDir\": [\"dir1\", \"dir2\"], " +
+                          "\"srcCore\": [\"core1\", \"core2\"], " +
+                          "\"updateChain\": \"someUpdateChain\", " +
+                          "\"async\": \"someRequestId\"}}");
+
+        assertEquals("mergeindexes", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+        assertEquals("someUpdateChain", 
v1Params.get(UpdateParams.UPDATE_CHAIN));
+        assertEquals("someRequestId", v1Params.get(ASYNC));
+        final List<String> indexDirs = 
Arrays.asList(v1Params.getParams("indexDir"));
+        assertEquals(2, indexDirs.size());
+        assertTrue(indexDirs.containsAll(List.of("dir1", "dir2")));
+        final List<String> srcCores = 
Arrays.asList(v1Params.getParams("srcCore"));
+        assertEquals(2, srcCores.size());
+        assertTrue(srcCores.containsAll(List.of("core1", "core2")));
+    }
+
+    @Test
+    public void testSplitCoreAllParams() throws Exception {
+        final SolrParams v1Params = 
captureConvertedV1Params("/cores/coreName", "POST",
+                "{" +
+                        "\"split\": {" +
+                        "\"path\": [\"path1\", \"path2\"], " +
+                        "\"targetCore\": [\"core1\", \"core2\"], " +
+                        "\"splitKey\": \"someSplitKey\", " +
+                        "\"getRanges\": true, " +
+                        "\"ranges\": \"range1,range2\", " +
+                        "\"async\": \"someRequestId\"}}");
+
+        assertEquals("split", v1Params.get(ACTION));
+        assertEquals("coreName", v1Params.get(CORE));
+        assertEquals("someSplitKey", v1Params.get(SPLIT_KEY));
+        assertEquals("range1,range2", v1Params.get(RANGES));
+        assertEquals("someRequestId", v1Params.get(ASYNC));
+        final List<String> pathEntries = 
Arrays.asList(v1Params.getParams(PATH));
+        assertEquals(2, pathEntries.size());
+        assertTrue(pathEntries.containsAll(List.of("path1", "path2")));
+        final List<String> targetCoreEntries = 
Arrays.asList(v1Params.getParams(TARGET_CORE));
+        assertEquals(2, targetCoreEntries.size());
+        assertTrue(targetCoreEntries.containsAll(List.of("core1", "core2")));
+    }
+
+    private SolrParams captureConvertedV1Params(String path, String method, 
String v2RequestBody) throws Exception {
+        final HashMap<String, String> parts = new HashMap<>();
+        final Api api = apiBag.lookup(path, method, parts);
+        final SolrQueryResponse rsp = new SolrQueryResponse();
+        final LocalSolrQueryRequest req = new LocalSolrQueryRequest(null, 
Maps.newHashMap()) {
+            @Override
+            public List<CommandOperation> getCommands(boolean validateInput) {
+                if (v2RequestBody == null) return Collections.emptyList();
+                return ApiBag.getCommandOperations(new 
ContentStreamBase.StringStream(v2RequestBody), api.getCommandSchema(), true);
+            }
+
+            @Override
+            public Map<String, String> getPathTemplateValues() {
+                return parts;
+            }
+
+            @Override
+            public String getHttpMethod() {
+                return method;
+            }
+        };
+
+
+        api.call(req, rsp);
+        
verify(mockCoreHandler).handleRequestBody(queryRequestCaptor.capture(), any());
+        return queryRequestCaptor.getValue().getParams();
+    }
+}
diff --git 
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreApiMapping.java 
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreApiMapping.java
index 52e78a6..fbd8444 100644
--- 
a/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreApiMapping.java
+++ 
b/solr/solrj/src/java/org/apache/solr/client/solrj/request/CoreApiMapping.java
@@ -35,12 +35,6 @@ import static 
org.apache.solr.client.solrj.request.CoreApiMapping.EndPoint.*;
  */
 public class CoreApiMapping {
   public enum Meta implements CommandMeta {
-    UNLOAD(PER_CORE_COMMANDS, POST, CoreAdminAction.UNLOAD, "unload", null),
-    RELOAD(PER_CORE_COMMANDS, POST, CoreAdminAction.RELOAD, "reload", null),
-    SWAP(PER_CORE_COMMANDS, POST, CoreAdminAction.SWAP, "swap", 
Collections.singletonMap("other", "with")),
-    RENAME(PER_CORE_COMMANDS, POST, CoreAdminAction.RENAME, "rename", 
Collections.singletonMap("other", "to")),
-    MERGEINDEXES(PER_CORE_COMMANDS, POST, CoreAdminAction.MERGEINDEXES, 
"merge-indexes", null),
-    SPLIT(PER_CORE_COMMANDS, POST, CoreAdminAction.SPLIT, "split", 
Collections.singletonMap("split.key", "splitKey")),
     PREPRECOVERY(PER_CORE_COMMANDS, POST, CoreAdminAction.PREPRECOVERY, 
"prep-recovery", null),
     REQUESTRECOVERY(PER_CORE_COMMANDS, POST, CoreAdminAction.REQUESTRECOVERY, 
"request-recovery", null),
     REQUESTSYNCSHARD(PER_CORE_COMMANDS, POST, 
CoreAdminAction.REQUESTSYNCSHARD, "request-sync-shard", null),
diff --git a/solr/solrj/src/resources/apispec/cores.core.Commands.json 
b/solr/solrj/src/resources/apispec/cores.core.Commands.json
index 34a70d6..0afe981 100644
--- a/solr/solrj/src/resources/apispec/cores.core.Commands.json
+++ b/solr/solrj/src/resources/apispec/cores.core.Commands.json
@@ -10,99 +10,6 @@
     ]
   },
   "commands": {
-    "reload": {
-      "type":"object",
-      "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-reload";,
-      "description": "Reloads a core. This is useful when you have made 
changes on disk such as editing the schema or solrconfig.xml files. Most APIs 
reload cores automatically, so this should not be necessary if changes were 
made with those APIs."
-    },
-    "swap": {
-      "type":"object",
-      "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-swap";,
-      "description": "Swaps the names of two existing Solr cores. This can be 
used to swap new content into production. The former core can be swapped back 
if necessary. Using this API is not supported in SolrCloud mode.",
-      "properties": {
-        "with": {
-          "type": "string",
-          "description": "The name of the other core to be swapped (the first 
core name is included in the request)."
-        },
-        "async": {
-          "type": "string",
-          "description": "Defines a request ID that can be used to track this 
action after it's submitted. The action will be processed asynchronously when 
this is defined."
-        }
-      },
-      "required": [
-        "with"
-      ]
-    },
-    "rename": {
-      "type": "object",
-      "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-rename";,
-      "description": "Change the name of a core.",
-      "properties": {
-        "to": {
-          "type": "string",
-          "description": "The new name for the core."
-        },
-        "async": {
-          "type": "string",
-          "description": "Defines a request ID that can be used to track this 
action after it's submitted. The action will be processed asynchronously when 
this is defined."
-        }
-      },
-      "required": [
-        "to"
-      ]
-    },
-    "unload": {
-      "type": "object",
-      "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-unload";,
-      "description": "Removes a core. Active requests would continue to be 
processed, but new requests will not be sent to the new core. If a core is 
registered under more than one name, only the name given in the request is 
removed.",
-      "properties": {
-        "deleteIndex": {
-          "type": "boolean",
-          "description": "If true, the index will be removed while unloading 
the core.",
-          "default": "false"
-        },
-        "deleteDataDir": {
-          "type": "boolean",
-          "description": "If true, the data directory and all sub-directories 
will be removed while unloading the core.",
-          "default": "false"
-        },
-        "deleteInstanceDir": {
-          "type": "boolean",
-          "description": "If true, everything related to the core, including 
the index, data, and conf directories, will be removed while unloading the 
core.",
-          "default": "false"
-        },
-        "async": {
-          "type": "string",
-          "description": "Defines a request ID that can be used to track this 
action after it's submitted. The action will be processed asynchronously when 
this is defined."
-        }
-      }
-    },
-    "merge-indexes": {
-      "type":"object",
-      "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-mergeindexes";,
-      "description":"Merges one or more indexes to another index. The indexes 
must have completed commits, and should be locked against writes until the 
merge is complete to avoid index corruption. The target core (which is the core 
that should be used as the endpoint for this command) must exist before using 
this command. A commit should also be performed on this core after the merge is 
complete.",
-      "properties": {
-        "indexDir": {
-          "type": "array",
-          "description": "A comma-separated list index directories for each 
source core that will be merged with the target core.",
-          "items": {
-            "type": "string"
-          }
-        },
-        "srcCore": {
-          "type": "array",
-          "description": "A comma-separated list of the names of each source 
core to be merged with the target core.",
-          "items": {
-            "type": "string"
-          }
-        },
-        "async": {
-          "type": "string",
-          "description": "Defines a request ID that can be used to track this 
action after it's submitted. The action will be processed asynchronously when 
this is defined."
-        }
-      }
-    },
-    "split":  { "#include": "cores.core.Commands.split"},
     "request-recovery": {
       "type":"object",
       "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-requestrecovery";,
diff --git a/solr/solrj/src/resources/apispec/cores.core.Commands.split.json 
b/solr/solrj/src/resources/apispec/cores.core.Commands.split.json
deleted file mode 100644
index e20a0e5..0000000
--- a/solr/solrj/src/resources/apispec/cores.core.Commands.split.json
+++ /dev/null
@@ -1,34 +0,0 @@
-{
-  "documentation": 
"https://solr.apache.org/guide/coreadmin-api.html#coreadmin-split";,
-  "description": "Allows splitting an index into two or more new indexes.",
-  "type": "object",
-  "properties": {
-    "path": {
-      "type": "array",
-      "description": "Directory path(s) in which a piece of the index will be 
written. This allows splitting the index before creating the cores to contain 
them. Note if using this approach that the indexes will not be able to receive 
updates until a new core has been created to handle the incoming updates. If 
you have already created the new cores, you should define the targetCore 
property instead.",
-      "items": {
-        "type": "string"
-      }
-    },
-    "targetCore": {
-      "type": "array",
-      "description": "The target Solr core(s) to which a piece of the index 
will be merged (if the target core already contains data). This requires that 
the cores have already been created. If the cores have not yet been created, 
use the path property instead.",
-      "items": {
-        "type": "string"
-      }
-    },
-    "splitKey": {
-      "type":"string",
-      "description": "A route key to use for splitting the index. This 
parameter is optional, but should not be defined if the ranges parameter is 
also defined."
-    },
-    "ranges": {
-      "type": "string",
-      "description": "A comma-separated list of hexadecimal hash ranges that 
will be used to split the core. This parameter is optional, but should not be 
defined if the splitKey parameter is also defined."
-    },
-    "async": {
-      "type": "string",
-      "description": "Defines a request ID that can be used to track this 
action after it's submitted. The action will be processed asynchronously when 
this is defined. This command can be long-running, so running it asynchronously 
is recommended."
-    }
-  }
-
-}
diff --git 
a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java 
b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
index 10cc866..e4c280e 100644
--- a/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
+++ b/solr/solrj/src/test/org/apache/solr/common/util/JsonValidatorTest.java
@@ -22,9 +22,6 @@ import org.apache.solr.SolrTestCaseJ4;
 import java.util.List;
 import java.util.Map;
 
-import static org.apache.solr.common.util.Utils.toJSONString;
-import static org.apache.solr.common.util.ValidatingJsonMap.NOT_NULL;
-
 public class JsonValidatorTest extends SolrTestCaseJ4  {
 
   public void testSchema() {
@@ -37,35 +34,13 @@ public class JsonValidatorTest extends SolrTestCaseJ4  {
 
 
   public void testSchemaValidation() {
-    // merge-indexes chosen to exercise string and array/list props.
-    ValidatingJsonMap spec = Utils.getSpec("cores.core.Commands").getSpec();
-    final Map<String, Object> mergeIndexesSchema = spec.getMap("commands", 
NOT_NULL).getMap("merge-indexes", NOT_NULL);
-    final JsonSchemaValidator mergeIndexesSchemaValidator = new 
JsonSchemaValidator(mergeIndexesSchema);
-
-    List<String> errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{async : x, 
indexDir: [ c1 , c2]}"));
-    assertNull(toJSONString(errs), errs);
-    errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{async : x, 
indexDir: [c1] }"));
-    assertNull(toJSONString(errs), errs);
-    errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{async : x, x:y, 
indexDir: [ c1 , c2]}"));
-    assertNotNull(toJSONString(errs), errs);
-    assertTrue(toJSONString(errs), errs.get(0).contains("Unknown"));
-    errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{async : 123, 
indexDir: c1 }"));
-    assertNotNull(toJSONString(errs), errs);
-    assertTrue(toJSONString(errs), errs.get(0).contains("expected"));
-    errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{x:y, indexDir: 
[ c1 , c2]}"));
-    assertTrue(toJSONString(errs), StrUtils.join(errs, 
'|').contains("Unknown"));
-    errs = 
mergeIndexesSchemaValidator.validateJson(Utils.fromJSONString("{async : x, 
indexDir: [ 1 , 2]}"));
-    assertFalse(toJSONString(errs), errs.isEmpty());
-    assertTrue(toJSONString(errs), errs.get(0).contains("expected"));
-
-
     final JsonSchemaValidator personSchemaValidator = new 
JsonSchemaValidator("{" +
         "  type:object," +
         "  properties: {" +
         "   age : {type: number}," +
         "   adult : {type: boolean}," +
         "   name: {type: string}}}");
-    errs = personSchemaValidator.validateJson(Utils.fromJSONString("{name:x, 
age:21, adult:true}"));
+    List<String> errs = 
personSchemaValidator.validateJson(Utils.fromJSONString("{name:x, age:21, 
adult:true}"));
     assertNull(errs);
     errs = personSchemaValidator.validateJson(Utils.fromJSONString("{name:x, 
age:'21', adult:'true'}"));
     assertNotNull(errs);

Reply via email to