This is an automated email from the ASF dual-hosted git repository. dsmiley pushed a commit to branch branch_10x in repository https://gitbox.apache.org/repos/asf/solr.git
commit 53bf2c09997001b1a729b1526bab884e482287fc Author: Jalaz Kumar <[email protected]> AuthorDate: Tue Oct 13 14:48:39 2026 +0530 SOLR-16396 | Migrate GET config sections updateHandler, directoryFactory, indexConfig, and codecFactory to JAX-RS. (#5023) (cherry picked from commit b5e8ae18c5269fe53a0815c0ff10a24887d3369c) --- .../SOLR-16396-config-get-components.yml | 9 ++++++ .../apache/solr/client/api/endpoint/ConfigApi.java | 12 +++++++ .../org/apache/solr/handler/SolrConfigHandler.java | 3 ++ .../apache/solr/handler/admin/api/GetConfig.java | 37 ++++++++++++++++++---- .../solr/handler/admin/api/GetConfigAPI.java | 9 ++---- .../handler/admin/api/GetConfigSolrCloudTest.java | 15 +++++++++ .../solr/handler/admin/api/GetConfigTest.java | 14 ++++++++ 7 files changed, 87 insertions(+), 12 deletions(-) diff --git a/changelog/unreleased/SOLR-16396-config-get-components.yml b/changelog/unreleased/SOLR-16396-config-get-components.yml new file mode 100644 index 00000000000..99a86733e03 --- /dev/null +++ b/changelog/unreleased/SOLR-16396-config-get-components.yml @@ -0,0 +1,9 @@ +title: + Migrate GET config sections updateHandler, directoryFactory, indexConfig, and codecFactory to JAX-RS. +type: changed +authors: + - name: Jalaz Kumar + nick: jaykay12 +links: + - name: SOLR-16396 + url: https://issues.apache.org/jira/browse/SOLR-16396 diff --git a/solr/api/src/java/org/apache/solr/client/api/endpoint/ConfigApi.java b/solr/api/src/java/org/apache/solr/client/api/endpoint/ConfigApi.java index cc9cecc1bb5..baaf4a9f785 100644 --- a/solr/api/src/java/org/apache/solr/client/api/endpoint/ConfigApi.java +++ b/solr/api/src/java/org/apache/solr/client/api/endpoint/ConfigApi.java @@ -23,6 +23,7 @@ import io.swagger.v3.oas.annotations.Parameter; import jakarta.ws.rs.DefaultValue; import jakarta.ws.rs.GET; import jakarta.ws.rs.Path; +import jakarta.ws.rs.PathParam; import jakarta.ws.rs.QueryParam; import org.apache.solr.client.api.model.ConfigInfoResponse; import org.apache.solr.client.api.model.ConfigOverlayResponse; @@ -68,5 +69,16 @@ public interface ConfigApi { @DefaultValue("-1") @Parameter(description = "Expected request-params znode version") int expectedParamsVersion); + + // TODO: Keep this regex in sync with GetConfig.MIGRATED_CONFIG_COMPONENTS + @GET + @Path("/{component:updateHandler|directoryFactory|indexConfig|codecFactory}") + @StoreApiParameters + @Operation( + summary = "Fetch a config section", + tags = {"config"}) + ConfigInfoResponse getConfigComponent( + @PathParam("component") @Parameter(description = "Name of the config component") + String component); } } diff --git a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java index 7f79e5a55e3..c31196831f9 100644 --- a/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java +++ b/solr/core/src/java/org/apache/solr/handler/SolrConfigHandler.java @@ -224,6 +224,9 @@ public class SolrConfigHandler extends RequestHandlerBase .getZnodeVersion( req.getParams().getInt(ConfigOverlay.NAME, -1), req.getParams().getInt(RequestParams.NAME, -1))); + } else if (GetConfig.MIGRATED_CONFIG_COMPONENTS.contains(parts.get(1))) { + V2ApiUtils.squashIntoSolrResponseWithoutHeader( + resp, new GetConfig(req).getConfigComponent(parts.get(1))); } else { Map<String, Object> m = getConfigDetails(parts.get(1), req); Map<String, Object> val = new LinkedHashMap<>(); diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfig.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfig.java index 80d46e7bac6..806cd1b3971 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfig.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfig.java @@ -27,6 +27,7 @@ import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.solr.api.JerseyResource; import org.apache.solr.client.api.endpoint.ConfigApi; import org.apache.solr.client.api.model.ConfigInfoResponse; @@ -48,6 +49,11 @@ import org.apache.solr.util.SolrPluginUtils; public class GetConfig extends JerseyResource implements ConfigApi.Get { + // TODO: Keep this in sync with @Path regex on ConfigApi.Get#getConfigComponent. + // TODO: Remove this set when remaining GET /config/{component} sections also migrate. + public static final Set<String> MIGRATED_CONFIG_COMPONENTS = + Set.of("updateHandler", "directoryFactory", "indexConfig", "codecFactory"); + private final SolrQueryRequest solrQueryRequest; @Inject @@ -89,15 +95,36 @@ public class GetConfig extends JerseyResource implements ConfigApi.Get { return response; } + @Override + @PermissionName(CONFIG_READ_PERM) + public ConfigInfoResponse getConfigComponent(String componentName) { + final var response = instantiateJerseyResponse(ConfigInfoResponse.class); + Map<String, Object> section = new LinkedHashMap<>(); + section.put(componentName, solrConfigAsMap().get(componentName)); + response.config = jsonSafeCopy(section); + return response; + } + + private Map<String, Object> solrConfigAsMap() { + return Utils.convertToMap(solrQueryRequest.getCore().getSolrConfig(), new LinkedHashMap<>()); + } + + @SuppressWarnings("unchecked") + private NullKeyTolerantMap jsonSafeCopy(Map<String, Object> map) { + final var jsonSafeCopy = new NullKeyTolerantMap("children"); + jsonSafeCopy.putAll((Map<String, Object>) Utils.getDeepCopy(map, 20, true)); + return jsonSafeCopy; + } + @SuppressWarnings({"unchecked"}) private Map<String, Object> buildConfigMap( SolrQueryRequest solrQueryRequest, boolean expandParams) { - Map<String, Object> map = - Utils.convertToMap(solrQueryRequest.getCore().getSolrConfig(), new LinkedHashMap<>()); + + Map<String, Object> configMap = solrConfigAsMap(); Map<String, Object> reqHandlers = (Map<String, Object>) - map.computeIfAbsent(SolrRequestHandler.TYPE, k -> new LinkedHashMap<>()); + configMap.computeIfAbsent(SolrRequestHandler.TYPE, k -> new LinkedHashMap<>()); List<PluginInfo> plugins = solrQueryRequest.getCore().getImplicitHandlers(); for (PluginInfo plugin : plugins) { if (SolrRequestHandler.TYPE.equals(plugin.type) && !reqHandlers.containsKey(plugin.name)) { @@ -111,9 +138,7 @@ public class GetConfig extends JerseyResource implements ConfigApi.Get { } } - final var jsonSafeCopy = new NullKeyTolerantMap("children"); - jsonSafeCopy.putAll((Map<String, Object>) Utils.getDeepCopy(map, 20, true)); - return jsonSafeCopy; + return jsonSafeCopy(configMap); } @SuppressWarnings({"unchecked", "rawtypes"}) diff --git a/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfigAPI.java b/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfigAPI.java index 6a0567c987c..1e67cb09c50 100644 --- a/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfigAPI.java +++ b/solr/core/src/java/org/apache/solr/handler/admin/api/GetConfigAPI.java @@ -28,8 +28,9 @@ import org.apache.solr.response.SolrQueryResponse; /** * V2 APIs for retrieving some or all configuration relevant to a particular collection (or core). * - * <p>This class covers legacy AnnotatedApi paths under GET /config: /params, /params{paramset}, - * /overlay, /znodeVersion, etc. + * <p>This class covers legacy AnnotatedApi paths under GET /config: /params, /params{paramset}, and + * remaining {@code /config/{component}} sections not yet migrated to {@link + * org.apache.solr.client.api.endpoint.ConfigApi.Get} */ public class GetConfigAPI { private final SolrConfigHandler configHandler; @@ -63,13 +64,9 @@ public class GetConfigAPI { "/config/query", "/config/requestHandler", "/config/searchComponent", - "/config/updateHandler", "/config/queryResponseWriter", "/config/initParams", "/config/listener", - "/config/directoryFactory", - "/config/indexConfig", - "/config/codecFactory", "/config/requestDispatcher", "/config/jmx", "/config/queryParser", diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigSolrCloudTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigSolrCloudTest.java index 7ce43a5ff3d..7b34a37bbb1 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigSolrCloudTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigSolrCloudTest.java @@ -76,4 +76,19 @@ public class GetConfigSolrCloudTest extends SolrCloudTestCase { assertTrue(response.znodeVersion.overlay >= -1); assertTrue(response.znodeVersion.params >= -1); } + + @Test + public void testGetConfigComponentFromCollection() throws Exception { + for (String component : GetConfig.MIGRATED_CONFIG_COMPONENTS) { + var request = + new ConfigApi.GetConfigComponent(IndexType.COLLECTION, COLLECTION_NAME, component); + var response = request.process(cluster.getSolrClient()); + + assertNotNull(component, response); + assertNull(component, response.error); + assertNotNull(component, response.config); + assertTrue(component, response.config.containsKey(component)); + assertEquals(component, 1, response.config.size()); + } + } } diff --git a/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigTest.java b/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigTest.java index a17d9258a18..b0fbbfa8035 100644 --- a/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigTest.java +++ b/solr/core/src/test/org/apache/solr/handler/admin/api/GetConfigTest.java @@ -80,4 +80,18 @@ public class GetConfigTest extends SolrTestCase { assertTrue(response.znodeVersion.overlay >= -1); assertTrue(response.znodeVersion.params >= -1); } + + @Test + public void testGetConfigComponentFromCore() throws Exception { + for (String component : GetConfig.MIGRATED_CONFIG_COMPONENTS) { + var request = new ConfigApi.GetConfigComponent(IndexType.CORE, CORE_NAME, component); + var response = request.process(solrTestRule.getSolrClient(CORE_NAME)); + + assertNotNull(component, response); + assertNull(component, response.error); + assertNotNull(component, response.config); + assertTrue(component, response.config.containsKey(component)); + assertEquals(component, 1, response.config.size()); + } + } }
