You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@solr.apache.org by st...@apache.org on 2023/08/16 18:08:54 UTC
[solr] branch branch_9x updated: SOLR-16859 Missing Proxy support for Http2SolrClient (#1779)
This is an automated email from the ASF dual-hosted git repository.
stillalex 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 35bf0faf4f9 SOLR-16859 Missing Proxy support for Http2SolrClient (#1779)
35bf0faf4f9 is described below
commit 35bf0faf4f9ad223e4c91cdc48effa3d5b224ab7
Author: Alex D <st...@apache.org>
AuthorDate: Wed Aug 16 11:04:51 2023 -0700
SOLR-16859 Missing Proxy support for Http2SolrClient (#1779)
(cherry picked from commit 21740acc3392645ffc08b4dd07e26e8235a03880)
---
solr/CHANGES.txt | 2 +
.../solr/client/solrj/impl/Http2SolrClient.java | 52 ++++++++++++
.../solrj/impl/Http2SolrClientProxyTest.java | 95 ++++++++++++++++++++++
3 files changed, 149 insertions(+)
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 3877ca15470..84197cffad2 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -57,6 +57,8 @@ Bug Fixes
* PR#1826: Allow looking up Solr Package repo when that URL references a raw repository.json hosted on Github when the file is JSON but the mimetype used is text/plain. (Eric Pugh)
+* SOLR-16859: Missing Proxy support for Http2SolrClient (Alex Deparvu)
+
Dependency Upgrades
---------------------
(No changes)
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
index 9ab097bd0ac..4be95d2d455 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Http2SolrClient.java
@@ -76,7 +76,12 @@ import org.apache.solr.common.util.SolrNamedThreadFactory;
import org.apache.solr.common.util.Utils;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.HttpClientTransport;
+import org.eclipse.jetty.client.HttpProxy;
+import org.eclipse.jetty.client.Origin.Address;
+import org.eclipse.jetty.client.Origin.Protocol;
import org.eclipse.jetty.client.ProtocolHandlers;
+import org.eclipse.jetty.client.ProxyConfiguration;
+import org.eclipse.jetty.client.Socks4Proxy;
import org.eclipse.jetty.client.api.AuthenticationStore;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.api.Response;
@@ -281,6 +286,8 @@ public class Http2SolrClient extends SolrClient {
if (builder.connectionTimeoutMillis != null)
httpClient.setConnectTimeout(builder.connectionTimeoutMillis);
+ setupProxy(builder, httpClient);
+
try {
httpClient.start();
} catch (Exception e) {
@@ -291,6 +298,29 @@ public class Http2SolrClient extends SolrClient {
return httpClient;
}
+ private void setupProxy(Builder builder, HttpClient httpClient) {
+ if (builder.proxyHost == null) {
+ return;
+ }
+ Address address = new Address(builder.proxyHost, builder.proxyPort);
+
+ final ProxyConfiguration.Proxy proxy;
+ if (builder.proxyIsSocks4) {
+ proxy = new Socks4Proxy(address, builder.proxyIsSecure);
+ } else {
+ final Protocol protocol;
+ if (builder.useHttp1_1) {
+ protocol = HttpClientTransportOverHTTP.HTTP11;
+ } else {
+ // see HttpClientTransportOverHTTP2#newOrigin
+ String protocolName = builder.proxyIsSecure ? "h2" : "h2c";
+ protocol = new Protocol(List.of(protocolName), false);
+ }
+ proxy = new HttpProxy(address, builder.proxyIsSecure, protocol);
+ }
+ httpClient.getProxyConfiguration().addProxy(proxy);
+ }
+
@Override
public void close() {
// we wait for async requests, so far devs don't want to give sugar for this
@@ -1046,6 +1076,10 @@ public class Http2SolrClient extends SolrClient {
protected ResponseParser responseParser;
private Set<String> urlParamNames;
private CookieStore cookieStore = getDefaultCookieStore();
+ private String proxyHost;
+ private int proxyPort;
+ private boolean proxyIsSocks4;
+ private boolean proxyIsSecure;
public Builder() {}
@@ -1269,6 +1303,24 @@ public class Http2SolrClient extends SolrClient {
this.cookieStore = cookieStore;
return this;
}
+
+ /**
+ * Setup a proxy
+ *
+ * @param host The proxy host
+ * @param port The proxy port
+ * @param isSocks4 If true creates an SOCKS 4 proxy, otherwise creates an HTTP proxy
+ * @param isSecure If true enables the secure flag on the proxy
+ * @return this Builder
+ */
+ public Builder withProxyConfiguration(
+ String host, int port, boolean isSocks4, boolean isSecure) {
+ this.proxyHost = host;
+ this.proxyPort = port;
+ this.proxyIsSocks4 = isSocks4;
+ this.proxyIsSecure = isSecure;
+ return this;
+ }
}
/**
diff --git a/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java
new file mode 100644
index 00000000000..09f3601c47b
--- /dev/null
+++ b/solr/solrj/src/test/org/apache/solr/client/solrj/impl/Http2SolrClientProxyTest.java
@@ -0,0 +1,95 @@
+/*
+ * 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.client.solrj.impl;
+
+import com.carrotsearch.randomizedtesting.RandomizedTest;
+import java.nio.file.Path;
+import java.util.Properties;
+import org.apache.solr.SolrJettyTestBase;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.embedded.JettyConfig;
+import org.apache.solr.embedded.JettySolrRunner;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+public class Http2SolrClientProxyTest extends SolrJettyTestBase {
+
+ // TODO add SSL test
+
+ @BeforeClass
+ public static void beforeTest() throws Exception {
+ RandomizedTest.assumeFalse(sslConfig.isSSLMode());
+
+ JettyConfig jettyConfig =
+ JettyConfig.builder().withSSLConfig(sslConfig.buildServerSSLConfig()).build();
+ createAndStartJettyWithProxy(legacyExampleCollection1SolrHome(), new Properties(), jettyConfig);
+ }
+
+ public static JettySolrRunner createAndStartJettyWithProxy(
+ String solrHome, Properties nodeProperties, JettyConfig jettyConfig) throws Exception {
+
+ initCore(null, null, solrHome);
+
+ Path coresDir = createTempDir().resolve("cores");
+
+ Properties props = new Properties();
+ props.setProperty("name", DEFAULT_TEST_CORENAME);
+ props.setProperty("configSet", "collection1");
+ props.setProperty("config", "${solrconfig:solrconfig.xml}");
+ props.setProperty("schema", "${schema:schema.xml}");
+
+ writeCoreProperties(coresDir.resolve("core"), props, "RestTestBase");
+
+ Properties nodeProps = new Properties(nodeProperties);
+ nodeProps.setProperty("coreRootDirectory", coresDir.toString());
+ nodeProps.setProperty("configSetBaseDir", solrHome);
+
+ jetty = new JettySolrRunner(solrHome, nodeProps, jettyConfig, true);
+ jetty.start();
+ port = jetty.getLocalPort();
+ return jetty;
+ }
+
+ /** Setup a simple http proxy and verify a request works */
+ @Test
+ public void testProxy() throws Exception {
+ var proxy = jetty.getProxy();
+ assertNotNull(proxy);
+
+ String host = proxy.getUrl().getHost();
+ String url = "http://" + host + ":" + (proxy.getUrl().getPort() + 10) + "/solr";
+
+ var builder =
+ new Http2SolrClient.Builder(url)
+ .withProxyConfiguration(host, proxy.getListenPort(), false, false);
+
+ try (Http2SolrClient client = builder.build()) {
+ String id = "1234";
+ SolrInputDocument doc = new SolrInputDocument();
+ doc.addField("id", id);
+ client.add(DEFAULT_TEST_COLLECTION_NAME, doc);
+ client.commit(DEFAULT_TEST_COLLECTION_NAME);
+ assertEquals(
+ 1,
+ client
+ .query(DEFAULT_TEST_COLLECTION_NAME, new SolrQuery("id:" + id))
+ .getResults()
+ .getNumFound());
+ }
+ }
+}