You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by ge...@apache.org on 2023/08/01 19:42:33 UTC

[solr] branch main updated: SOLR-16847 Give v2 APIs access to solrconfig.xml config (#1778)

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 9c43fc138b0 SOLR-16847 Give v2 APIs access to solrconfig.xml config (#1778)
9c43fc138b0 is described below

commit 9c43fc138b04c1420b912ec4371eea77335f905b
Author: Alex <st...@apache.org>
AuthorDate: Tue Aug 1 12:42:26 2023 -0700

    SOLR-16847 Give v2 APIs access to solrconfig.xml config (#1778)
    
    Prior to this commit, v2 APIs had no clean way to access any solrconfig.xml
    configuration for their associated "requestHandler".  This commit introduces
    an interface, APIConfigProvider, which allows us to inject this configuration
    to v2 API classes at call time in a "strongly-typed" way.
---
 solr/CHANGES.txt                                   |  1 +
 .../src/java/org/apache/solr/core/PluginBag.java   | 10 ++-
 .../org/apache/solr/jersey/APIConfigProvider.java  | 34 ++++++++++
 .../solr/jersey/APIConfigProviderBinder.java       | 34 ++++++++++
 .../test/org/apache/solr/core/PluginBagTest.java   | 74 ++++++++++++++++++++++
 5 files changed, 151 insertions(+), 2 deletions(-)

diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index c6335b86c24..9647e7d7eee 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -67,6 +67,7 @@ Improvements
 
 * SOLR-16883: Postlogs tool for indexing Solr logs in Solr now supported on Windows by converting it to a Solr CLI command: `bin/solr postlogs`.   `bin/postlogs` script marked deprected.  (Eric Pugh, Will White)
 
+* SOLR-16847: v2 APIs are now able to access any applicable solrconfig.xml "requestHandler" configuration. (Alex Deparvu via Jason Gerlowski)
 
 Optimizations
 ---------------------
diff --git a/solr/core/src/java/org/apache/solr/core/PluginBag.java b/solr/core/src/java/org/apache/solr/core/PluginBag.java
index c70bdd4af9d..629c480d5ce 100644
--- a/solr/core/src/java/org/apache/solr/core/PluginBag.java
+++ b/solr/core/src/java/org/apache/solr/core/PluginBag.java
@@ -43,6 +43,8 @@ import org.apache.solr.common.util.StrUtils;
 import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.handler.api.V2ApiUtils;
 import org.apache.solr.handler.component.SearchComponent;
+import org.apache.solr.jersey.APIConfigProvider;
+import org.apache.solr.jersey.APIConfigProviderBinder;
 import org.apache.solr.jersey.JerseyApplications;
 import org.apache.solr.pkg.PackagePluginHolder;
 import org.apache.solr.request.SolrRequestHandler;
@@ -264,10 +266,14 @@ public class PluginBag<T> implements AutoCloseable {
                 // See RequestMetricHandling javadocs for a better understanding of this
                 // resource->RH
                 // mapping
-                if (inst instanceof RequestHandlerBase) {
-                  jaxrsResourceRegistry.put(jerseyClazz, (RequestHandlerBase) inst);
+                if (apiSupport instanceof RequestHandlerBase) {
+                  jaxrsResourceRegistry.put(jerseyClazz, (RequestHandlerBase) apiSupport);
                 }
               }
+              if (apiSupport instanceof APIConfigProvider) {
+                jerseyResources.register(
+                    new APIConfigProviderBinder((APIConfigProvider<?>) apiSupport));
+              }
             }
           }
         }
diff --git a/solr/core/src/java/org/apache/solr/jersey/APIConfigProvider.java b/solr/core/src/java/org/apache/solr/jersey/APIConfigProvider.java
new file mode 100644
index 00000000000..fd250949ffd
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/jersey/APIConfigProvider.java
@@ -0,0 +1,34 @@
+/*
+ * 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.jersey;
+
+import org.apache.solr.jersey.APIConfigProvider.APIConfig;
+import org.glassfish.hk2.api.Factory;
+
+/**
+ * Interface to be implemented by the Request Handlers that need to provide some custom
+ * configuration to the V2 APIs
+ */
+public interface APIConfigProvider<T extends APIConfig> extends Factory<T> {
+
+  @Override
+  default void dispose(T instance) {}
+
+  Class<T> getConfigClass();
+
+  public interface APIConfig {}
+}
diff --git a/solr/core/src/java/org/apache/solr/jersey/APIConfigProviderBinder.java b/solr/core/src/java/org/apache/solr/jersey/APIConfigProviderBinder.java
new file mode 100644
index 00000000000..8e4258aa43d
--- /dev/null
+++ b/solr/core/src/java/org/apache/solr/jersey/APIConfigProviderBinder.java
@@ -0,0 +1,34 @@
+/*
+ * 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.jersey;
+
+import org.glassfish.hk2.utilities.binding.AbstractBinder;
+
+/** Jersey binder for APIConfigProvider */
+public class APIConfigProviderBinder extends AbstractBinder {
+
+  private final APIConfigProvider<?> cfgProvider;
+
+  public APIConfigProviderBinder(APIConfigProvider<?> cfgProvider) {
+    this.cfgProvider = cfgProvider;
+  }
+
+  @Override
+  protected void configure() {
+    bindFactory(cfgProvider).to(cfgProvider.getConfigClass());
+  }
+}
diff --git a/solr/core/src/test/org/apache/solr/core/PluginBagTest.java b/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
index f0281038197..bfc585b8840 100644
--- a/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
+++ b/solr/core/src/test/org/apache/solr/core/PluginBagTest.java
@@ -19,12 +19,24 @@ package org.apache.solr.core;
 
 import static org.mockito.Mockito.mock;
 
+import java.util.Collection;
+import java.util.List;
 import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.api.ApiSupport;
+import org.apache.solr.api.JerseyResource;
+import org.apache.solr.handler.RequestHandlerBase;
 import org.apache.solr.handler.admin.ConfigSetsHandler;
+import org.apache.solr.handler.admin.api.CollectionPropertyAPI;
 import org.apache.solr.handler.component.SearchComponent;
 import org.apache.solr.handler.configsets.ListConfigSetsAPI;
+import org.apache.solr.jersey.APIConfigProvider;
+import org.apache.solr.jersey.APIConfigProvider.APIConfig;
+import org.apache.solr.jersey.APIConfigProviderBinder;
 import org.apache.solr.jersey.JerseyApplications;
+import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
+import org.apache.solr.response.SolrQueryResponse;
+import org.apache.solr.security.AuthorizationContext;
 import org.glassfish.jersey.server.ResourceConfig;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -90,4 +102,66 @@ public class PluginBagTest extends SolrTestCaseJ4 {
 
     assertTrue(handlerPluginBag.getJerseyEndpoints().isRegistered(ListConfigSetsAPI.class));
   }
+
+  @Test
+  public void testApiConfig() {
+    PluginBag<SolrRequestHandler> handlerPluginBag =
+        new PluginBag<>(SolrRequestHandler.class, null);
+    ResourceConfig config = handlerPluginBag.getJerseyEndpoints();
+
+    assertFalse(config.isRegistered(APIConfigProviderBinder.class));
+
+    EmptyRequestHandler handler1 = new EmptyRequestHandler();
+    handlerPluginBag.put("/foo", handler1);
+
+    // check v2 api was registered
+    handler1.getJerseyResources().forEach(c -> assertTrue(config.isRegistered(c)));
+    // check binder for config is present
+    assertTrue(config.isRegistered(APIConfigProviderBinder.class));
+  }
+
+  /** An empty handler for testing */
+  private static class EmptyRequestHandler extends RequestHandlerBase
+      implements ApiSupport, APIConfigProvider<EmptyAPIConfig> {
+
+    private final EmptyAPIConfig config = new EmptyAPIConfig();
+
+    @Override
+    public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp) {
+      // nothing!
+    }
+
+    @Override
+    public String getDescription() {
+      return null;
+    }
+
+    @Override
+    public Name getPermissionName(AuthorizationContext request) {
+      return Name.ALL;
+    }
+
+    @Override
+    public Boolean registerV2() {
+      return Boolean.TRUE;
+    }
+
+    @Override
+    public Collection<Class<? extends JerseyResource>> getJerseyResources() {
+      // random pick of v2 api
+      return List.of(CollectionPropertyAPI.class);
+    }
+
+    @Override
+    public EmptyAPIConfig provide() {
+      return config;
+    }
+
+    @Override
+    public Class<EmptyAPIConfig> getConfigClass() {
+      return EmptyAPIConfig.class;
+    }
+  }
+
+  private static class EmptyAPIConfig implements APIConfig {}
 }