Skip to content
11 changes: 11 additions & 0 deletions changelog/unreleased/SOLR-16396-config-remaining-get-sections.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
title: >
Migrate remaining GET /config/{component} sections to JAX-RS.
V2 renames listener, queryParser, valueSourceParser, transformer, updateProcessor, queryConverter and expressibles to
listeners, queryParsers, valueSourceParsers, transformers, updateProcessors, queryConverters and expressibles respectively. (V1 unchanged)
type: changed
authors:
- name: Jalaz Kumar
nick: jaykay12
links:
- name: SOLR-16396
url: https://issues.apache.org/jira/browse/SOLR-16396
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,10 @@ ConfigZnodeVersionResponse getZnodeVersion(
@Parameter(description = "Expected request-params znode version")
int expectedParamsVersion);

// TODO: Keep this regex in sync with GetConfig.MIGRATED_CONFIG_COMPONENTS ("searchComponents"
// and "queryResponseWriters" here are the external, pluralized names for the internal
// "searchComponent"/"queryResponseWriter" sections; see GetConfig#toExternalComponentName)
// TODO: Keep this regex in sync with GetConfig.MIGRATED_CONFIG_COMPONENTS
@GET
@Path(
"/{component:updateHandler|directoryFactory|indexConfig|codecFactory|query|searchComponents|queryResponseWriters}")
"/{component:updateHandler|directoryFactory|indexConfig|codecFactory|query|searchComponents|queryResponseWriters|luceneMatchVersion|initParams|listeners|requestDispatcher|jmx|queryParsers|valueSourceParsers|transformers|updateProcessors|updateRequestProcessorChain|queryConverters|caches|circuitBreaker|expressibles|schemaFactory|restManager|statsCache|recoveryStrategy|indexReaderFactory|indexConfigdeletionPolicy|updateHandlerupdateLog}")
@StoreApiParameters
@Operation(
summary = "Fetch a config section",
Expand All @@ -84,12 +82,14 @@ ConfigInfoResponse getConfigComponent(
@PathParam("component") @Parameter(description = "Name of the config component")
String component);

// TODO: Keep this regex in sync with GetConfig.MIGRATED_CONFIG_COMPONENTS ("searchComponents"
// and "queryResponseWriters" here are the external, pluralized names for the internal
// "searchComponent"/"queryResponseWriter" sections; see GetConfig#toExternalComponentName)
// TODO: Keep this regex in sync with GetConfig.MIGRATED_CONFIG_COMPONENTS. Sections without
// REQUIRE_NAME in SolrConfig's plugin registration (initParams, listeners,
// updateRequestProcessorChain, circuitBreaker) are deliberately excluded here: they're
// serialized as a List rather than a name-keyed Map, so by-name lookup isn't meaningful for
// them (see GetConfig.filterByComponentName).
@GET
@Path(
"/{component:updateHandler|directoryFactory|indexConfig|codecFactory|query|searchComponents|queryResponseWriters}/{componentName}")
"/{component:updateHandler|directoryFactory|indexConfig|codecFactory|query|searchComponents|queryResponseWriters|queryParsers|valueSourceParsers|transformers|updateProcessors|queryConverters|caches|expressibles|schemaFactory|restManager|statsCache|recoveryStrategy|indexReaderFactory}/{componentName}")
@StoreApiParameters
@Operation(
summary = "Fetch a single named entry within a config section",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,15 +231,9 @@ private void handleGET() {
: getConfig.getConfigComponentByName(
parts.get(1), componentName, req.getParams().getBool("meta", false)));
} else {
Map<String, Object> m = getConfigDetails(parts.get(1), req);
Map<String, Object> val = new LinkedHashMap<>();
val.put(parts.get(1), m.get(parts.get(1)));
String componentName = req.getParams().get("componentName");
if (componentName != null) {
GetConfig.filterByComponentName(
val, parts.get(1), componentName, req.getParams().getBool("meta", false), req);
}
resp.add("config", val);
throw new SolrException(
SolrException.ErrorCode.NOT_FOUND,
"No config API for path: /config/" + parts.get(1));
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,14 +66,43 @@ public class GetConfig extends JerseyResource implements ConfigApi.Get {
"codecFactory",
"query",
"searchComponent",
"queryResponseWriter");
"queryResponseWriter",
"luceneMatchVersion",
"initParams",
"listener",
"requestDispatcher",
"jmx",
"queryParser",
"valueSourceParser",
"transformer",
"updateProcessor",
"updateRequestProcessorChain",
"queryConverter",
"cache",
"circuitBreaker",
"expressible",
"schemaFactory",
"restManager",
"statsCache",
"recoveryStrategy",
"indexReaderFactory",
"indexConfigdeletionPolicy",
"updateHandlerupdateLog");

// v2-only renames: external (URL/response-key) component name -> internal SolrConfig section
// name. v1's GET /config/{component} keeps using the internal names unchanged.
private static final Map<String, String> EXTERNAL_TO_INTERNAL_COMPONENT_NAME =
Map.of(
"searchComponents", "searchComponent",
"queryResponseWriters", "queryResponseWriter");
"queryResponseWriters", "queryResponseWriter",
"listeners", "listener",
"queryParsers", "queryParser",
"valueSourceParsers", "valueSourceParser",
"transformers", "transformer",
"updateProcessors", "updateProcessor",
"queryConverters", "queryConverter",
"expressibles", "expressible",
"caches", "cache");

private static String toInternalComponentName(String externalName) {
return EXTERNAL_TO_INTERNAL_COMPONENT_NAME.getOrDefault(externalName, externalName);
Expand Down Expand Up @@ -166,10 +195,19 @@ public static void filterByComponentName(
String componentName,
boolean meta,
SolrQueryRequest req) {
Map pluginNameVsPluginInfo = (Map) section.get(component);
if (pluginNameVsPluginInfo == null) {
Object sectionValue = section.get(component);
if (sectionValue == null) {
return;
}
if (!(sectionValue instanceof Map) && !(sectionValue instanceof MapWriter)) {
// e.g. circuitBreaker, initParams, listener, updateRequestProcessorChain: plugins declared
// without REQUIRE_NAME are serialized as a List, not a name-keyed Map, so filtering by name
// doesn't apply to them.
throw new SolrException(
SolrException.ErrorCode.NOT_FOUND,
component + " does not support filtering by componentName");
}
Map pluginNameVsPluginInfo = (Map) sectionValue;

Object o =
pluginNameVsPluginInfo instanceof MapWriter
Expand Down Expand Up @@ -252,7 +290,7 @@ private Map<String, Object> buildConfigMap(
return jsonSafeCopy(configMap);
}

@SuppressWarnings({"unchecked", "rawtypes"})
@SuppressWarnings("unchecked")
private Map<String, Object> expandUseParams(SolrQueryRequest req, Object plugin) {
Map<String, Object> pluginInfo;
if (plugin instanceof Map) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,30 +59,7 @@ public void getSingleParamSet(SolrQueryRequest req, SolrQueryResponse rsp) {
// Every name SolrConfig.writeMap can emit.
// Delete a path from this list when that section is migrated to Jersey
@EndPoint(
path = {
"/config/luceneMatchVersion",
"/config/requestHandler",
"/config/initParams",
"/config/listener",
"/config/requestDispatcher",
"/config/jmx",
"/config/queryParser",
"/config/valueSourceParser",
"/config/transformer",
"/config/updateProcessor",
"/config/updateRequestProcessorChain",
"/config/queryConverter",
"/config/cache",
"/config/circuitBreaker",
"/config/expressible",
"/config/schemaFactory",
"/config/restManager",
"/config/statsCache",
"/config/recoveryStrategy",
"/config/indexReaderFactory",
"/config/indexConfigdeletionPolicy",
"/config/updateHandlerupdateLog"
},
path = {"/config/requestHandler"},
method = GET,
permission = CONFIG_READ_PERM)
public void getComponentConfig(SolrQueryRequest req, SolrQueryResponse rsp) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,11 +50,6 @@ public void populateApiBag() {
@Test
public void testGetSingleComponentConfig() {
assertAnnotatedApiExistsFor("GET", "/config/requestHandler");
assertAnnotatedApiExistsFor("GET", "/config/jmx");
assertAnnotatedApiExistsFor("GET", "/config/requestDispatcher");
assertAnnotatedApiExistsFor("GET", "/config/luceneMatchVersion");
assertAnnotatedApiExistsFor("GET", "/config/indexConfigdeletionPolicy");
assertAnnotatedApiExistsFor("GET", "/config/updateHandlerupdateLog");
}

@Test
Expand Down
Loading