Skip to content

Commit f811df5

Browse files
refactor: extract shared SolrClientHelper and fix idle-timeout gap in ZK path
- Extract applyAuthAndProxy into SolrClientHelper to eliminate identical auth/proxy logic duplicated between SolrEmitter and SolrPipesIterator; helper reads proxy from HttpClientFactory directly (both callers already copy proxy config into the factory before building the Jetty client) - Add missing withIdleTimeout to the ZK (CloudSolrClient) path in both classes so all three timeouts (request, connection, idle) are applied consistently across both ZK and LB paths Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent d84e2bb commit f811df5

3 files changed

Lines changed: 58 additions & 33 deletions

File tree

tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/emitter/solr/SolrEmitter.java

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import org.apache.tika.parser.ParseContext;
4141
import org.apache.tika.pipes.api.emitter.AbstractEmitter;
4242
import org.apache.tika.pipes.api.emitter.EmitData;
43+
import org.apache.tika.pipes.plugin.solr.SolrClientHelper;
4344
import org.apache.tika.plugins.ExtensionConfig;
4445
import org.apache.tika.utils.StringUtils;
4546

@@ -110,18 +111,19 @@ private static SolrClient buildSolrClient(SolrEmitterConfig config) throws TikaC
110111
if (config.solrUrls() == null || config.solrUrls().isEmpty()) {
111112
// Use ZooKeeper-based CloudSolrClient
112113
HttpJettySolrClient.Builder jettyClientBuilder = new HttpJettySolrClient.Builder();
113-
applyAuthAndProxy(jettyClientBuilder, httpClientFactory, config.proxyHost(), config.proxyPort());
114+
SolrClientHelper.applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
114115
jettyClientBuilder
115116
.withRequestTimeout(httpClientFactory.getRequestTimeoutMillis(), TimeUnit.MILLISECONDS)
116-
.withConnectionTimeout(config.getConnectionTimeoutMillisOrDefault(), TimeUnit.MILLISECONDS);
117+
.withConnectionTimeout(config.getConnectionTimeoutMillisOrDefault(), TimeUnit.MILLISECONDS)
118+
.withIdleTimeout(config.getSocketTimeoutMillisOrDefault(), TimeUnit.MILLISECONDS);
117119

118120
return new CloudSolrClient.Builder(config.solrZkHosts(), Optional.ofNullable(config.solrZkChroot()))
119121
.withInternalClientBuilder(jettyClientBuilder)
120122
.build();
121123
} else {
122124
// Use direct URL-based LBJettySolrClient
123125
HttpJettySolrClient.Builder jettyClientBuilder = new HttpJettySolrClient.Builder();
124-
applyAuthAndProxy(jettyClientBuilder, httpClientFactory, config.proxyHost(), config.proxyPort());
126+
SolrClientHelper.applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
125127
jettyClientBuilder
126128
.withRequestTimeout(httpClientFactory.getRequestTimeoutMillis(), TimeUnit.MILLISECONDS)
127129
.withConnectionTimeout(config.getConnectionTimeoutMillisOrDefault(), TimeUnit.MILLISECONDS)
@@ -134,20 +136,6 @@ private static SolrClient buildSolrClient(SolrEmitterConfig config) throws TikaC
134136
}
135137
}
136138

137-
private static void applyAuthAndProxy(HttpJettySolrClient.Builder builder, HttpClientFactory factory,
138-
String proxyHost, Integer proxyPort) throws TikaConfigException {
139-
if (!StringUtils.isBlank(factory.getUserName())) {
140-
if (!"basic".equalsIgnoreCase(factory.getAuthScheme())) {
141-
throw new TikaConfigException("Only 'basic' auth scheme is supported by HttpJettySolrClient; got: '"
142-
+ factory.getAuthScheme() + "'");
143-
}
144-
builder.withBasicAuthCredentials(factory.getUserName(), factory.getPassword());
145-
}
146-
if (!StringUtils.isBlank(proxyHost) && proxyPort != null && proxyPort > 0) {
147-
builder.withProxyConfiguration(proxyHost, proxyPort, false, false);
148-
}
149-
}
150-
151139
@Override
152140
public void emit(String emitKey, List<Metadata> metadataList, ParseContext parseContext) throws IOException {
153141
if (metadataList == null || metadataList.isEmpty()) {

tika-pipes/tika-pipes-plugins/tika-pipes-solr/src/main/java/org/apache/tika/pipes/iterator/solr/SolrPipesIterator.java

Lines changed: 5 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
import org.apache.tika.pipes.api.emitter.EmitKey;
4747
import org.apache.tika.pipes.api.fetcher.FetchKey;
4848
import org.apache.tika.pipes.pipesiterator.PipesIteratorBase;
49+
import org.apache.tika.pipes.plugin.solr.SolrClientHelper;
4950
import org.apache.tika.plugins.ExtensionConfig;
5051
import org.apache.tika.utils.StringUtils;
5152

@@ -182,17 +183,18 @@ private SolrClient createSolrClient() throws TikaConfigException {
182183

183184
if (solrUrls.isEmpty()) {
184185
HttpJettySolrClient.Builder jettyClientBuilder = new HttpJettySolrClient.Builder();
185-
applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
186+
SolrClientHelper.applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
186187
jettyClientBuilder
187188
.withRequestTimeout(httpClientFactory.getRequestTimeoutMillis(), TimeUnit.MILLISECONDS)
188-
.withConnectionTimeout(config.getConnectionTimeoutMillis(), TimeUnit.MILLISECONDS);
189+
.withConnectionTimeout(config.getConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
190+
.withIdleTimeout(config.getSocketTimeoutMillis(), TimeUnit.MILLISECONDS);
189191

190192
return new CloudSolrClient.Builder(solrZkHosts, Optional.ofNullable(config.getSolrZkChroot()))
191193
.withInternalClientBuilder(jettyClientBuilder)
192194
.build();
193195
}
194196
HttpJettySolrClient.Builder jettyClientBuilder = new HttpJettySolrClient.Builder();
195-
applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
197+
SolrClientHelper.applyAuthAndProxy(jettyClientBuilder, httpClientFactory);
196198
jettyClientBuilder
197199
.withRequestTimeout(httpClientFactory.getRequestTimeoutMillis(), TimeUnit.MILLISECONDS)
198200
.withConnectionTimeout(config.getConnectionTimeoutMillis(), TimeUnit.MILLISECONDS)
@@ -204,17 +206,4 @@ private SolrClient createSolrClient() throws TikaConfigException {
204206
return new LBJettySolrClient.Builder(jettyClient, endpoints).build();
205207
}
206208

207-
private static void applyAuthAndProxy(HttpJettySolrClient.Builder builder,
208-
HttpClientFactory factory) throws TikaConfigException {
209-
if (!StringUtils.isBlank(factory.getUserName())) {
210-
if (!"basic".equalsIgnoreCase(factory.getAuthScheme())) {
211-
throw new TikaConfigException("Only 'basic' auth scheme is supported by HttpJettySolrClient; got: '"
212-
+ factory.getAuthScheme() + "'");
213-
}
214-
builder.withBasicAuthCredentials(factory.getUserName(), factory.getPassword());
215-
}
216-
if (!StringUtils.isBlank(factory.getProxyHost()) && factory.getProxyPort() > 0) {
217-
builder.withProxyConfiguration(factory.getProxyHost(), factory.getProxyPort(), false, false);
218-
}
219-
}
220209
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Licensed to the Apache Software Foundation (ASF) under one or more
3+
* contributor license agreements. See the NOTICE file distributed with
4+
* this work for additional information regarding copyright ownership.
5+
* The ASF licenses this file to You under the Apache License, Version 2.0
6+
* (the "License"); you may not use this file except in compliance with
7+
* the License. You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
package org.apache.tika.pipes.plugin.solr;
18+
19+
import org.apache.solr.client.solrj.jetty.HttpJettySolrClient;
20+
21+
import org.apache.tika.client.HttpClientFactory;
22+
import org.apache.tika.exception.TikaConfigException;
23+
import org.apache.tika.utils.StringUtils;
24+
25+
public final class SolrClientHelper {
26+
27+
private SolrClientHelper() {}
28+
29+
/**
30+
* Applies authentication and proxy settings to a {@link HttpJettySolrClient.Builder}.
31+
* Only basic auth is supported; a non-basic auth scheme will throw {@link TikaConfigException}.
32+
* Proxy is only configured when both host and a positive port are present on the factory.
33+
*/
34+
public static void applyAuthAndProxy(HttpJettySolrClient.Builder builder,
35+
HttpClientFactory factory) throws TikaConfigException {
36+
if (!StringUtils.isBlank(factory.getUserName())) {
37+
if (!"basic".equalsIgnoreCase(factory.getAuthScheme())) {
38+
throw new TikaConfigException(
39+
"Only 'basic' auth scheme is supported by HttpJettySolrClient; got: '"
40+
+ factory.getAuthScheme() + "'");
41+
}
42+
builder.withBasicAuthCredentials(factory.getUserName(), factory.getPassword());
43+
}
44+
if (!StringUtils.isBlank(factory.getProxyHost()) && factory.getProxyPort() > 0) {
45+
builder.withProxyConfiguration(factory.getProxyHost(), factory.getProxyPort(), false, false);
46+
}
47+
}
48+
}

0 commit comments

Comments
 (0)