You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by no...@apache.org on 2016/10/03 18:49:32 UTC
lucene-solr:master: SOLR-9520: Kerberos delegation support in SolrJ
Repository: lucene-solr
Updated Branches:
refs/heads/master e7ade287e -> 3a76ef119
SOLR-9520: Kerberos delegation support in SolrJ
Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/3a76ef11
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/3a76ef11
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/3a76ef11
Branch: refs/heads/master
Commit: 3a76ef11931d6cf5e86002d9c23f03c79f663fc0
Parents: e7ade28
Author: Noble Paul <no...@apache.org>
Authored: Tue Oct 4 00:19:20 2016 +0530
Committer: Noble Paul <no...@apache.org>
Committed: Tue Oct 4 00:19:20 2016 +0530
----------------------------------------------------------------------
solr/CHANGES.txt | 1 +
.../TestSolrCloudWithDelegationTokens.java | 26 ++++--
.../solr/client/solrj/impl/CloudSolrClient.java | 46 +++++++---
.../solr/client/solrj/impl/HttpSolrClient.java | 59 ++++--------
.../client/solrj/impl/LBHttpSolrClient.java | 94 ++++++++++++++------
5 files changed, 138 insertions(+), 88 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a76ef11/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index b402625..bbcc42b 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -115,6 +115,7 @@ New Features
* SOLR-9205: Added method LukeResponse.getSchemaFlags() which returns field
information as an EnumSet (Fengtan, Alan Woodward)
+* SOLR-9520: Kerberos delegation support in SolrJ (Ishan Chattopadhyaya, noble)
Bug Fixes
----------------------
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a76ef11/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
index a58ec8c..c3fa813 100644
--- a/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
+++ b/solr/core/src/test/org/apache/solr/cloud/TestSolrCloudWithDelegationTokens.java
@@ -20,7 +20,10 @@ import junit.framework.Assert;
import org.apache.hadoop.util.Time;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
+import org.apache.solr.client.solrj.impl.LBHttpSolrClient;
+import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
@@ -171,30 +174,39 @@ public class TestSolrCloudWithDelegationTokens extends SolrTestCaseJ4 {
private int getStatusCode(String token, final String user, final String op, HttpSolrClient client)
throws Exception {
- HttpSolrClient delegationTokenServer =
- new HttpSolrClient.Builder(client.getBaseURL().toString())
- .withDelegationToken(token)
+ SolrClient delegationTokenClient;
+ if (random().nextBoolean()) delegationTokenClient = new HttpSolrClient.Builder(client.getBaseURL().toString())
+ .withKerberosDelegationToken(token)
+ .withResponseParser(client.getParser())
+ .build();
+ else delegationTokenClient = new CloudSolrClient.Builder()
+ .withZkHost((miniCluster.getZkServer().getZkAddress()))
+ .withLBHttpSolrClientBuilder(new LBHttpSolrClient.Builder()
.withResponseParser(client.getParser())
- .build();
+ .withHttpSolrClientBuilder(
+ new HttpSolrClient.Builder()
+ .withKerberosDelegationToken(token)
+ ))
+ .build();
try {
ModifiableSolrParams p = new ModifiableSolrParams();
if (user != null) p.set(USER_PARAM, user);
if (op != null) p.set("op", op);
SolrRequest req = getAdminRequest(p);
if (user != null || op != null) {
- Set<String> queryParams = new HashSet<String>();
+ Set<String> queryParams = new HashSet<>();
if (user != null) queryParams.add(USER_PARAM);
if (op != null) queryParams.add("op");
req.setQueryParams(queryParams);
}
try {
- delegationTokenServer.request(req, null, null);
+ delegationTokenClient.request(req, null);
return HttpStatus.SC_OK;
} catch (HttpSolrClient.RemoteSolrException re) {
return re.code();
}
} finally {
- delegationTokenServer.close();
+ delegationTokenClient.close();
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a76ef11/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
index 834e956..6a186ce 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/CloudSolrClient.java
@@ -341,7 +341,7 @@ public class CloudSolrClient extends SolrClient {
* the {@link HttpClient} instance to be used for all requests. The provided httpClient should use a
* multi-threaded connection manager. If null, a default HttpClient will be used.
* @param lbSolrClient
- * LBHttpSolrServer instance for requests. If null, a default HttpClient will be used.
+ * LBHttpSolrClient instance for requests. If null, a default LBHttpSolrClient will be used.
* @param updatesToLeaders
* If true, sends updates to shard leaders.
*
@@ -350,7 +350,7 @@ public class CloudSolrClient extends SolrClient {
*/
@Deprecated
public CloudSolrClient(Collection<String> zkHosts, String chroot, HttpClient httpClient, LBHttpSolrClient lbSolrClient, boolean updatesToLeaders) {
- this(zkHosts, chroot, httpClient, lbSolrClient, updatesToLeaders, false);
+ this(zkHosts, chroot, httpClient, lbSolrClient, null, updatesToLeaders, false);
}
/**
@@ -371,23 +371,31 @@ public class CloudSolrClient extends SolrClient {
* the {@link HttpClient} instance to be used for all requests. The provided httpClient should use a
* multi-threaded connection manager. If null, a default HttpClient will be used.
* @param lbSolrClient
- * LBHttpSolrServer instance for requests. If null, a default HttpClient will be used.
+ * LBHttpSolrClient instance for requests. If null, a default LBHttpSolrClient will be used.
+ * @param lbHttpSolrClientBuilder
+ * LBHttpSolrClient builder to construct the LBHttpSolrClient. If null, a default builder will be used.
* @param updatesToLeaders
* If true, sends updates to shard leaders.
* @param directUpdatesToLeadersOnly
* If true, sends direct updates to shard leaders only.
*/
- private CloudSolrClient(Collection<String> zkHosts, String chroot, HttpClient httpClient, LBHttpSolrClient lbSolrClient,
- boolean updatesToLeaders, boolean directUpdatesToLeadersOnly) {
+ private CloudSolrClient(Collection<String> zkHosts,
+ String chroot,
+ HttpClient httpClient,
+ LBHttpSolrClient lbSolrClient,
+ LBHttpSolrClient.Builder lbHttpSolrClientBuilder,
+ boolean updatesToLeaders,
+ boolean directUpdatesToLeadersOnly) {
+ this.clientIsInternal = httpClient == null;
+ this.shutdownLBHttpSolrServer = lbSolrClient == null;
+ if(lbHttpSolrClientBuilder != null) lbSolrClient = lbHttpSolrClientBuilder.build();
+ if(lbSolrClient != null) httpClient = lbSolrClient.getHttpClient();
+ this.myClient = httpClient == null ? HttpClientUtil.createClient(null) : httpClient;
+ if (lbSolrClient == null) lbSolrClient = createLBHttpSolrClient(myClient);
+ this.lbClient = lbSolrClient;
this.zkHost = buildZkHostString(zkHosts, chroot);
this.updatesToLeaders = updatesToLeaders;
this.directUpdatesToLeadersOnly = directUpdatesToLeadersOnly;
-
- this.clientIsInternal = httpClient == null;
- this.myClient = httpClient == null ? HttpClientUtil.createClient(null) : httpClient;
-
- this.shutdownLBHttpSolrServer = lbSolrClient == null;
- this.lbClient = lbSolrClient == null ? createLBHttpSolrClient(myClient) : lbSolrClient;
}
/**
@@ -475,7 +483,7 @@ public class CloudSolrClient extends SolrClient {
public ResponseParser getParser() {
return lbClient.getParser();
}
-
+
/**
* Note: This setter method is <b>not thread-safe</b>.
*
@@ -1553,6 +1561,7 @@ public class CloudSolrClient extends SolrClient {
private HttpClient httpClient;
private String zkChroot;
private LBHttpSolrClient loadBalancedSolrClient;
+ private LBHttpSolrClient.Builder lbClientBuilder;
private boolean shardLeadersOnly;
private boolean directUpdatesToLeadersOnly;
@@ -1578,11 +1587,20 @@ public class CloudSolrClient extends SolrClient {
/**
* Provides a {@link HttpClient} for the builder to use when creating clients.
*/
+ public Builder withLBHttpSolrClientBuilder(LBHttpSolrClient.Builder lbHttpSolrClientBuilder) {
+ this.lbClientBuilder = lbHttpSolrClientBuilder;
+ return this;
+ }
+
+ /**
+ * Provides a {@link HttpClient} for the builder to use when creating clients.
+ */
public Builder withHttpClient(HttpClient httpClient) {
this.httpClient = httpClient;
return this;
}
-
+
+
/**
* Provide a series of ZooKeeper client endpoints for the builder to use when creating clients.
*
@@ -1652,7 +1670,7 @@ public class CloudSolrClient extends SolrClient {
* Create a {@link CloudSolrClient} based on the provided configuration.
*/
public CloudSolrClient build() {
- return new CloudSolrClient(zkHosts, zkChroot, httpClient, loadBalancedSolrClient,
+ return new CloudSolrClient(zkHosts, zkChroot, httpClient, loadBalancedSolrClient, lbClientBuilder,
shardLeadersOnly, directUpdatesToLeadersOnly);
}
}
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a76ef11/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
----------------------------------------------------------------------
diff --git a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
index 222119c..e43fd33 100644
--- a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
+++ b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpSolrClient.java
@@ -23,7 +23,6 @@ import java.lang.invoke.MethodHandles;
import java.net.ConnectException;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
-import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
@@ -31,7 +30,6 @@ import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Set;
-import java.util.TreeSet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
@@ -746,43 +744,6 @@ public class HttpSolrClient extends SolrClient {
}
}
- private static class DelegationTokenHttpSolrClient extends HttpSolrClient {
- private final String DELEGATION_TOKEN_PARAM = "delegation";
- private final String delegationToken;
-
- public DelegationTokenHttpSolrClient(String baseURL,
- HttpClient client,
- ResponseParser parser,
- boolean allowCompression,
- String delegationToken) {
- super(baseURL, client, parser, allowCompression);
- if (delegationToken == null) {
- throw new IllegalArgumentException("Delegation token cannot be null");
- }
- this.delegationToken = delegationToken;
- setQueryParams(new TreeSet<String>(Arrays.asList(DELEGATION_TOKEN_PARAM)));
- invariantParams = new ModifiableSolrParams();
- invariantParams.set(DELEGATION_TOKEN_PARAM, delegationToken);
- }
-
- @Override
- protected HttpRequestBase createMethod(final SolrRequest request, String collection) throws IOException, SolrServerException {
- SolrParams params = request.getParams();
- if (params.getParams(DELEGATION_TOKEN_PARAM) != null) {
- throw new IllegalArgumentException(DELEGATION_TOKEN_PARAM + " parameter not supported");
- }
- return super.createMethod(request, collection);
- }
-
- @Override
- public void setQueryParams(Set<String> queryParams) {
- if (queryParams == null || !queryParams.contains(DELEGATION_TOKEN_PARAM)) {
- throw new IllegalArgumentException("Query params must contain " + DELEGATION_TOKEN_PARAM);
- }
- super.setQueryParams(queryParams);
- }
- }
-
/**
* Constructs {@link HttpSolrClient} instances from provided configuration.
*/
@@ -792,7 +753,16 @@ public class HttpSolrClient extends SolrClient {
private ResponseParser responseParser;
private boolean compression;
private String delegationToken;
-
+
+ public Builder() {
+ this.responseParser = new BinaryResponseParser();
+ }
+
+ public Builder withBaseSolrUrl(String baseSolrUrl) {
+ this.baseSolrUrl = baseSolrUrl;
+ return this;
+ }
+
/**
* Create a Builder object, based on the provided Solr URL.
*
@@ -832,6 +802,15 @@ public class HttpSolrClient extends SolrClient {
/**
* Use a delegation token for authenticating via the KerberosPlugin
*/
+ public Builder withKerberosDelegationToken(String delegationToken) {
+ this.delegationToken = delegationToken;
+ return this;
+ }
+
+ @Deprecated
+ /**
+ * @deprecated use {@link withKerberosDelegationToken(String)} instead
+ */
public Builder withDelegationToken(String delegationToken) {
this.delegationToken = delegationToken;
return this;
http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/3a76ef11/solr/solrj/src/java/org/apache/solr/client/solrj/impl/LBHttpSolrClient.java
----------------------------------------------------------------------
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 74b0943..3cb59cd 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
@@ -118,6 +118,7 @@ public class LBHttpSolrClient extends SolrClient {
private final HttpClient httpClient;
private final boolean clientIsInternal;
+ private HttpSolrClient.Builder httpSolrClientBuilder;
private final AtomicInteger counter = new AtomicInteger(-1);
private static final SolrQuery solrQuery = new SolrQuery("*:*");
@@ -247,22 +248,30 @@ public class LBHttpSolrClient extends SolrClient {
* @deprecated use {@link Builder} instead. This will soon be a protected
* method and will only be available for use in implementing subclasses.
*/
+ public LBHttpSolrClient(HttpSolrClient.Builder httpSolrClientBuilder,
+ HttpClient httpClient, String... solrServerUrl) {
+ clientIsInternal = httpClient == null;
+ this.httpSolrClientBuilder = httpSolrClientBuilder;
+ httpClient = constructClient(null);
+ this.httpClient = httpClient;
+ if (solrServerUrl != null) {
+ for (String s : solrServerUrl) {
+ ServerWrapper wrapper = new ServerWrapper(makeSolrClient(s));
+ aliveServers.put(wrapper.getKey(), wrapper);
+ }
+ }
+ updateAliveList();
+ }
+
+ /**
+ * The provided httpClient should use a multi-threaded connection manager
+ * @deprecated use {@link Builder} instead. This will soon be a protected
+ * method and will only be available for use in implementing subclasses.
+ */
@Deprecated
public LBHttpSolrClient(HttpClient httpClient, ResponseParser parser, String... solrServerUrl) {
clientIsInternal = (httpClient == null);
- if (httpClient == null) {
- ModifiableSolrParams params = new ModifiableSolrParams();
- if (solrServerUrl.length > 1) {
- // we prefer retrying another server
- params.set(HttpClientUtil.PROP_USE_RETRY, false);
- } else {
- params.set(HttpClientUtil.PROP_USE_RETRY, true);
- }
- this.httpClient = HttpClientUtil.createClient(params);
- } else {
- this.httpClient = httpClient;
- }
-
+ this.httpClient = httpClient == null ? constructClient(solrServerUrl) : httpClient;
this.parser = parser;
for (String s : solrServerUrl) {
@@ -271,7 +280,18 @@ public class LBHttpSolrClient extends SolrClient {
}
updateAliveList();
}
-
+
+ private HttpClient constructClient(String[] solrServerUrl) {
+ ModifiableSolrParams params = new ModifiableSolrParams();
+ if (solrServerUrl != null && solrServerUrl.length > 1) {
+ // we prefer retrying another server
+ params.set(HttpClientUtil.PROP_USE_RETRY, false);
+ } else {
+ params.set(HttpClientUtil.PROP_USE_RETRY, true);
+ }
+ return HttpClientUtil.createClient(params);
+ }
+
public Set<String> getQueryParams() {
return queryParams;
}
@@ -294,15 +314,19 @@ public class LBHttpSolrClient extends SolrClient {
}
protected HttpSolrClient makeSolrClient(String server) {
- HttpSolrClient client = new HttpSolrClient.Builder(server)
- .withHttpClient(httpClient)
- .withResponseParser(parser)
- .build();
- if (connectionTimeout != null) {
- client.setConnectionTimeout(connectionTimeout);
- }
- if (soTimeout != null) {
- client.setSoTimeout(soTimeout);
+ HttpSolrClient client;
+ if (httpSolrClientBuilder != null) {
+ synchronized (this) {
+ client = httpSolrClientBuilder
+ .withBaseSolrUrl(server)
+ .withHttpClient(httpClient)
+ .build();
+ }
+ } else {
+ client = new HttpSolrClient.Builder(server)
+ .withHttpClient(httpClient)
+ .withResponseParser(parser)
+ .build();
}
if (requestWriter != null) {
client.setRequestWriter(requestWriter);
@@ -787,11 +811,16 @@ public class LBHttpSolrClient extends SolrClient {
private final List<String> baseSolrUrls;
private HttpClient httpClient;
private ResponseParser responseParser;
-
+ private HttpSolrClient.Builder httpSolrClientBuilder;
+
public Builder() {
- this.baseSolrUrls = new ArrayList<String>();
+ this.baseSolrUrls = new ArrayList<>();
this.responseParser = new BinaryResponseParser();
}
+
+ public HttpSolrClient.Builder getHttpSolrClientBuilder() {
+ return httpSolrClientBuilder;
+ }
/**
* Provide a Solr endpoint to be used when configuring {@link LBHttpSolrClient} instances.
@@ -831,13 +860,24 @@ public class LBHttpSolrClient extends SolrClient {
this.responseParser = responseParser;
return this;
}
-
+
+ /**
+ * Provides a {@link HttpSolrClient.Builder} to be used for building the internally used clients.
+ */
+ public Builder withHttpSolrClientBuilder(HttpSolrClient.Builder builder) {
+ this.httpSolrClientBuilder = builder;
+ return this;
+ }
+
/**
* Create a {@link HttpSolrClient} based on provided configuration.
*/
public LBHttpSolrClient build() {
final String[] baseUrlArray = new String[baseSolrUrls.size()];
- return new LBHttpSolrClient(httpClient, responseParser, baseSolrUrls.toArray(baseUrlArray));
+ String[] solrServerUrls = baseSolrUrls.toArray(baseUrlArray);
+ return httpSolrClientBuilder != null ?
+ new LBHttpSolrClient(httpSolrClientBuilder, httpClient, solrServerUrls) :
+ new LBHttpSolrClient(httpClient, responseParser, solrServerUrls);
}
}
}