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 2024/03/04 14:21:25 UTC

(solr) branch branch_9x updated: SOLR-17066: Add deprecation warnings to 9x methods (#2302)

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

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


The following commit(s) were added to refs/heads/branch_9x by this push:
     new a139617be08 SOLR-17066: Add deprecation warnings to 9x methods (#2302)
a139617be08 is described below

commit a139617be08b8374b3d43d002fd58d6fd9cad6c2
Author: Jason Gerlowski <ge...@apache.org>
AuthorDate: Mon Mar 4 09:21:19 2024 -0500

    SOLR-17066: Add deprecation warnings to 9x methods (#2302)
    
    SOLR-17066 introduced the `LBSolrClient.Endpoint` class, and modified
    several "LB" client methods to use it on "main".  This commit adds the
    corresponding deprecation notices to branch_9x, so that users can be
    notified of these changes and start to upgrade their apps where
    appropriate/required.
---
 .../handler/component/HttpShardHandlerFactory.java |   2 +-
 .../client/solrj/impl/CloudHttp2SolrClient.java    |   2 +-
 .../solr/client/solrj/impl/LBHttp2SolrClient.java  |  52 +++++++++
 .../solr/client/solrj/impl/LBHttpSolrClient.java   | 110 ++++++++++++++++++
 .../solr/client/solrj/impl/LBSolrClient.java       | 123 +++++++++++++++++++++
 5 files changed, 287 insertions(+), 2 deletions(-)

diff --git a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
index 5b227359701..79e0ad48681 100644
--- a/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
+++ b/solr/core/src/java/org/apache/solr/handler/component/HttpShardHandlerFactory.java
@@ -287,7 +287,7 @@ public class HttpShardHandlerFactory extends ShardHandlerFactory
             .withMaxConnectionsPerHost(maxConnectionsPerHost)
             .build();
     this.defaultClient.addListenerFactory(this.httpListenerFactory);
-    this.loadbalancer = new LBHttp2SolrClient.Builder(defaultClient).build();
+    this.loadbalancer = new LBHttp2SolrClient.Builder(defaultClient, new String[0]).build();
 
     initReplicaListTransformers(getParameter(args, "replicaRouting", null, sb));
 
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
index 5eab2dea39b..6838a575755 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudHttp2SolrClient.java
@@ -83,7 +83,7 @@ public class CloudHttp2SolrClient extends CloudSolrClient {
     // locks.
     this.locks = objectList(builder.parallelCacheRefreshesLocks);
 
-    this.lbClient = new LBHttp2SolrClient.Builder(myClient).build();
+    this.lbClient = new LBHttp2SolrClient.Builder(myClient, new String[0]).build();
   }
 
   @Override
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttp2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttp2SolrClient.java
index 6cfada08541..f971e21fcd7 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttp2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttp2SolrClient.java
@@ -101,11 +101,20 @@ public class LBHttp2SolrClient extends LBSolrClient {
     this.defaultCollection = builder.defaultCollection;
   }
 
+  /**
+   * @deprecated Use {@link #getClient(Endpoint)} instead.
+   */
+  @Deprecated
   @Override
   protected SolrClient getClient(String baseUrl) {
     return solrClient;
   }
 
+  @Override
+  protected SolrClient getClient(Endpoint endpoint) {
+    return solrClient;
+  }
+
   /**
    * Note: This setter method is <b>not thread-safe</b>.
    *
@@ -352,12 +361,55 @@ public class LBHttp2SolrClient extends LBSolrClient {
      * In this case the client is more flexible and can be used to send requests to any cores. Users
      * can still provide a "default" collection if desired through use of {@link
      * #withDefaultCollection(String)}.
+     *
+     * @deprecated use {@link #Builder(Http2SolrClient, Endpoint...)} instead
      */
+    @Deprecated
     public Builder(Http2SolrClient http2Client, String... baseSolrUrls) {
       this.http2SolrClient = http2Client;
       this.baseSolrUrls = baseSolrUrls;
     }
 
+    /**
+     * Create a Builder object, based on the provided solrClient and endpoint objects.
+     *
+     * <p>Endpoint instances come in two main flavors:
+     *
+     * <p>1) Endpoints representing a particular core or collection
+     *
+     * <pre>
+     *   SolrClient client = new LBHttp2SolrClient.Builder(
+     *           client, new LBSolrClient.Endpoint("http://my-solr-server:8983/solr", "core1"))
+     *       .build();
+     *   QueryResponse resp = client.query(new SolrQuery("*:*"));
+     * </pre>
+     *
+     * Note that when a core is provided in the endpoint, queries and other requests can be made
+     * without mentioning the core explicitly. However, the client can only send requests to that
+     * core. Attempts to make core-agnostic requests, or requests for other cores will fail.
+     *
+     * <p>2) Endpoints representing the root Solr path (i.e. "/solr")
+     *
+     * <pre>
+     *   SolrClient client = new LBHttp2SolrClient.Builder(
+     *           client, new LBSolrClient.Endpoint("http://my-solr-server:8983/solr"))
+     *       .build();
+     *   QueryResponse resp = client.query("core1", new SolrQuery("*:*"));
+     * </pre>
+     *
+     * In this case the client is more flexible and can be used to send requests to any cores. Users
+     * can still provide a "default" collection if desired through use of {@link
+     * #withDefaultCollection(String)}.
+     */
+    public Builder(Http2SolrClient http2Client, Endpoint... endpoints) {
+      this.http2SolrClient = http2Client;
+
+      this.baseSolrUrls = new String[endpoints.length];
+      for (int i = 0; i < endpoints.length; i++) {
+        this.baseSolrUrls[i] = endpoints[i].getUrl();
+      }
+    }
+
     /**
      * LBHttpSolrServer keeps pinging the dead servers at fixed interval to find if it is alive. Use
      * this to set that interval
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
index b595701aec5..dd86f170669 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 import org.apache.http.client.HttpClient;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.common.params.ModifiableSolrParams;
+import org.apache.solr.common.util.URLUtil;
 
 /**
  * LBHttpSolrClient or "LoadBalanced HttpSolrClient" is a load balancing wrapper around {@link
@@ -117,6 +118,14 @@ public class LBHttpSolrClient extends LBSolrClient {
     return HttpClientUtil.createClient(params);
   }
 
+  protected HttpSolrClient makeSolrClient(Endpoint endpoint) {
+    return makeSolrClient(endpoint.getUrl());
+  }
+
+  /**
+   * @deprecated use {@link #makeSolrClient(Endpoint)} instead
+   */
+  @Deprecated
   protected HttpSolrClient makeSolrClient(String server) {
     HttpSolrClient client;
     if (httpSolrClientBuilder != null) {
@@ -159,6 +168,10 @@ public class LBHttpSolrClient extends LBSolrClient {
     return client;
   }
 
+  /**
+   * @deprecated use {@link #getClient(Endpoint)} instead
+   */
+  @Deprecated
   @Override
   protected SolrClient getClient(String baseUrl) {
     SolrClient client = urlToClient.get(baseUrl);
@@ -169,12 +182,26 @@ public class LBHttpSolrClient extends LBSolrClient {
     }
   }
 
+  @Override
+  protected SolrClient getClient(Endpoint endpoint) {
+    return getClient(endpoint.getUrl());
+  }
+
+  /**
+   * @deprecated use {@link #removeSolrEndpoint(Endpoint)} instead
+   */
+  @Deprecated
   @Override
   public String removeSolrServer(String server) {
     urlToClient.remove(server);
     return super.removeSolrServer(server);
   }
 
+  @Override
+  public String removeSolrEndpoint(Endpoint endpoint) {
+    return removeSolrServer(endpoint.getUrl());
+  }
+
   @Override
   public void close() {
     super.close();
@@ -256,12 +283,91 @@ public class LBHttpSolrClient extends LBSolrClient {
      *
      * In this case the client is more flexible and can be used to send requests to any cores. This
      * flexibility though requires that the core is specified on all requests.
+     *
+     * @deprecated use {@link #withBaseEndpoint(String)} or {@link #withCollectionEndpoint(String,
+     *     String)} instead, based on the type of URL string currently being supplied
      */
+    @Deprecated
     public Builder withBaseSolrUrl(String baseSolrUrl) {
       this.baseSolrUrls.add(baseSolrUrl);
       return this;
     }
 
+    /**
+     * Provide a "base" Solr URL to be used when configuring {@link LBHttpSolrClient} instances.
+     *
+     * <p>Method may be called multiple times. All provided values will be used. However, all
+     * endpoints must be of the same type: providing a mix of "base" endpoints via this method and
+     * core/collection endpoints via {@link #withCollectionEndpoint(String, String)} is prohibited.
+     *
+     * <p>Users who use this method to provide base Solr URLs may specify a "default collection" for
+     * their requests using {@link #withDefaultCollection(String)} if they wish to avoid needing to
+     * specify a collection or core on relevant requests.
+     *
+     * @param rootUrl the base URL for a Solr node, in the form "http[s]://hostname:port/solr"
+     */
+    public Builder withBaseEndpoint(String rootUrl) {
+      this.baseSolrUrls.add(rootUrl);
+      return this;
+    }
+
+    /**
+     * Provide multiple "base" Solr URLs to be used when configuring {@link LBHttpSolrClient}
+     * instances.
+     *
+     * <p>Method may be called multiple times. All provided values will be used. However, all
+     * endpoints must be of the same type: providing a mix of"base" endpoints via this method and
+     * core/collection endpoints via {@link #withCollectionEndpoint(String, String)} is prohibited.
+     *
+     * <p>Users who use this method to provide base Solr URLs may specify a "default collection" for
+     * their requests using {@link #withDefaultCollection(String)} if they wish to avoid needing to
+     * specify a collection or core on relevant requests.
+     *
+     * @param baseSolrUrls Solr base URLs, in the form "http[s]://hostname:port/solr"
+     */
+    public Builder withBaseEndpoints(String... baseSolrUrls) {
+      for (String baseSolrUrl : baseSolrUrls) {
+        this.baseSolrUrls.add(baseSolrUrl);
+      }
+      return this;
+    }
+
+    /**
+     * Provide a core/collection Solr endpoint to be used when configuring {@link LBHttpSolrClient}
+     * instances.
+     *
+     * <p>Method may be called multiple times. All provided values will be used. However, all
+     * endpoints must be of the same type: providing a mix of "core" endpoints via this method and
+     * base endpoints via {@link #withBaseEndpoint(String)} is prohibited.
+     *
+     * @param rootUrl the base URL for a Solr node, in the form "http[s]://hostname:port/solr"
+     * @param collection the Solr core or collection to target
+     */
+    public Builder withCollectionEndpoint(String rootUrl, String collection) {
+      this.baseSolrUrls.add(URLUtil.buildCoreUrl(rootUrl, collection));
+      return this;
+    }
+
+    /**
+     * Provide multiple core/collection endpoints to be used when configuring {@link
+     * LBHttpSolrClient} instances.
+     *
+     * <p>Method may be called multiple times. All provided values will be used. However, all
+     * endpoints must be of the same type: providing a mix of "core" endpoints via this method and
+     * base endpoints via {@link #withBaseEndpoint(String)} is prohibited.
+     *
+     * @param endpoints endpoint instances pointing to distinct cores/collections
+     */
+    public Builder withCollectionEndpoints(Endpoint... endpoints) {
+      if (endpoints != null) {
+        for (Endpoint e : endpoints) {
+          this.baseSolrUrls.add(URLUtil.buildCoreUrl(e.getBaseUrl(), e.getCore()));
+        }
+      }
+
+      return this;
+    }
+
     /**
      * Provide Solr endpoints to be used when configuring {@link LBHttpSolrClient} instances.
      *
@@ -294,7 +400,11 @@ public class LBHttpSolrClient extends LBSolrClient {
      * In this case the client is more flexible and can be used to send requests to any cores. Users
      * can still provide a "default" collection if desired through use of {@link
      * #withDefaultCollection(String)}.
+     *
+     * @deprecated use either {@link #withBaseEndpoints(String...)} or {@link
+     *     #withCollectionEndpoints(Endpoint...)}, based on the type of URL strings currently used.
      */
+    @Deprecated
     public Builder withBaseSolrUrls(String... solrUrls) {
       for (String baseSolrUrl : solrUrls) {
         this.baseSolrUrls.add(baseSolrUrl);
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
index 9202768bcf6..87e203b1cab 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBSolrClient.java
@@ -28,18 +28,21 @@ import java.net.SocketTimeoutException;
 import java.net.URL;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
 import org.apache.solr.client.solrj.ResponseParser;
 import org.apache.solr.client.solrj.SolrClient;
 import org.apache.solr.client.solrj.SolrQuery;
@@ -100,6 +103,82 @@ public abstract class LBSolrClient extends SolrClient {
     solrQuery.setDistrib(false);
   }
 
+  /**
+   * A Solr endpoint for {@link LBSolrClient} to include in its load-balancing
+   *
+   * <p>Used in many places instead of the more common String URL to allow {@link LBSolrClient} to
+   * more easily determine whether a URL is a "base" or "core-aware" URL.
+   */
+  public static class Endpoint {
+    private final String baseUrl;
+    private final String core;
+
+    /**
+     * Creates an {@link Endpoint} representing a "base" URL of a Solr node
+     *
+     * @param baseUrl a base Solr URL, in the form "http[s]://host:port/solr"
+     */
+    public Endpoint(String baseUrl) {
+      this(baseUrl, null);
+    }
+
+    /**
+     * Create an {@link Endpoint} representing a Solr core or collection
+     *
+     * @param baseUrl a base Solr URL, in the form "http[s]://host:port/solr"
+     * @param core the name of a Solr core or collection
+     */
+    public Endpoint(String baseUrl, String core) {
+      this.baseUrl = normalize(baseUrl);
+      this.core = core;
+    }
+
+    /**
+     * Return the base URL of the Solr node this endpoint represents
+     *
+     * @return a base Solr URL, in the form "http[s]://host:port/solr"
+     */
+    public String getBaseUrl() {
+      return baseUrl;
+    }
+
+    /**
+     * The core or collection this endpoint represents
+     *
+     * @return a core/collection name, or null if this endpoint doesn't represent a particular core.
+     */
+    public String getCore() {
+      return core;
+    }
+
+    /** Get the full URL, possibly including the collection/core if one was provided */
+    public String getUrl() {
+      if (core == null) {
+        return baseUrl;
+      }
+      return baseUrl + "/" + core;
+    }
+
+    @Override
+    public String toString() {
+      return getUrl();
+    }
+
+    @Override
+    public int hashCode() {
+      return Objects.hash(baseUrl, core);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+      if (this == obj) return true;
+      if (!(obj instanceof Endpoint)) return false;
+      final Endpoint rhs = (Endpoint) obj;
+
+      return Objects.equals(baseUrl, rhs.baseUrl) && Objects.equals(core, rhs.core);
+    }
+  }
+
   protected static class ServerWrapper {
     final String baseUrl;
 
@@ -245,10 +324,24 @@ public abstract class LBSolrClient extends SolrClient {
     protected int numDeadServersToTry;
     private final Integer numServersToTry;
 
+    /**
+     * @deprecated use {@link #Req(SolrRequest, Collection)} instead
+     */
+    @Deprecated
     public Req(SolrRequest<?> request, List<String> servers) {
       this(request, servers, null);
     }
 
+    public Req(SolrRequest<?> request, Collection<Endpoint> servers) {
+      this(
+          request,
+          servers.stream().map(endpoint -> endpoint.getUrl()).collect(Collectors.toList()));
+    }
+
+    /**
+     * @deprecated use {@link #Req(SolrRequest, Collection, Integer)} instead
+     */
+    @Deprecated
     public Req(SolrRequest<?> request, List<String> servers, Integer numServersToTry) {
       this.request = request;
       this.servers = servers;
@@ -256,10 +349,22 @@ public abstract class LBSolrClient extends SolrClient {
       this.numServersToTry = numServersToTry;
     }
 
+    public Req(SolrRequest<?> request, Collection<Endpoint> servers, Integer numServersToTry) {
+      this(
+          request,
+          servers.stream().map(endpoint -> endpoint.getUrl()).collect(Collectors.toList()),
+          numServersToTry);
+    }
+
     public SolrRequest<?> getRequest() {
       return request;
     }
 
+    /**
+     * @deprecated will be replaced with a similar method in 10.0 that returns {@link Endpoint}
+     *     instances instead.
+     */
+    @Deprecated
     public List<String> getServers() {
       return servers;
     }
@@ -435,6 +540,8 @@ public abstract class LBSolrClient extends SolrClient {
 
   protected abstract SolrClient getClient(String baseUrl);
 
+  protected abstract SolrClient getClient(Endpoint endpoint);
+
   protected Exception addZombie(String serverStr, Exception e) {
     ServerWrapper wrapper = createServerWrapper(serverStr);
     wrapper.standard = false;
@@ -571,10 +678,22 @@ public abstract class LBSolrClient extends SolrClient {
     }
   }
 
+  /**
+   * @deprecated use {@link #addSolrServer(Endpoint)} instead
+   */
+  @Deprecated
   public void addSolrServer(String server) throws MalformedURLException {
     addToAlive(createServerWrapper(server));
   }
 
+  public void addSolrServer(Endpoint server) throws MalformedURLException {
+    addSolrServer(server.getUrl());
+  }
+
+  /**
+   * @deprecated use {@link #removeSolrEndpoint(Endpoint)} instead
+   */
+  @Deprecated
   public String removeSolrServer(String server) {
     try {
       server = new URL(server).toExternalForm();
@@ -592,6 +711,10 @@ public abstract class LBSolrClient extends SolrClient {
     return null;
   }
 
+  public String removeSolrEndpoint(Endpoint endpoint) {
+    return removeSolrServer(endpoint.getUrl());
+  }
+
   /**
    * Tries to query a live server. A SolrServerException is thrown if all servers are dead. If the
    * request failed due to IOException then the live server is moved to dead pool and the request is