Hi, Something went wrong with the Java 9 assume in TestSolrCloudWithHadoopAuthPlugin. It should just ignore the test, but for some reason it fails the test. See recent Jenkins failures!
Uwe ----- Uwe Schindler Achterdiek 19, D-28357 Bremen http://www.thetaphi.de eMail: [email protected] > -----Original Message----- > From: [email protected] [mailto:[email protected]] > Sent: Monday, December 19, 2016 4:16 PM > To: [email protected] > Subject: [1/2] lucene-solr:master: SOLR-9513: Generic Hadoop authentication > plugins, GenericHadoopAuthPlugin and > ConfigurableInternodeAuthHadoopPlugin > > Repository: lucene-solr > Updated Branches: > refs/heads/master 321c6f090 -> a1a8b2864 > > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/core/src/test/org/apache/solr/security/hadoop/Te > stImpersonationWithHadoopAuth.java > ---------------------------------------------------------------------- > diff --git > a/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationWi > thHadoopAuth.java > b/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationW > ithHadoopAuth.java > new file mode 100644 > index 0000000..ed8397b > --- /dev/null > +++ > b/solr/core/src/test/org/apache/solr/security/hadoop/TestImpersonationW > ithHadoopAuth.java > @@ -0,0 +1,215 @@ > +/* > + * 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.security.hadoop; > + > +import static > org.apache.solr.security.HttpParamDelegationTokenPlugin.USER_PARAM; > +import static org.apache.solr.security.hadoop.ImpersonationUtil.*; > + > +import java.net.InetAddress; > +import java.nio.charset.Charset; > +import java.nio.file.Files; > +import java.nio.file.Path; > +import java.util.HashMap; > +import java.util.Map; > + > +import org.apache.lucene.util.Constants; > +import org.apache.solr.client.solrj.SolrClient; > +import org.apache.solr.client.solrj.embedded.JettySolrRunner; > +import org.apache.solr.client.solrj.impl.HttpSolrClient; > +import org.apache.solr.client.solrj.request.CollectionAdminRequest; > +import org.apache.solr.cloud.SolrCloudTestCase; > +import org.apache.solr.common.params.ModifiableSolrParams; > +import org.apache.solr.common.util.Utils; > +import org.apache.solr.security.HadoopAuthPlugin; > +import org.apache.solr.servlet.SolrRequestParsers; > +import org.junit.AfterClass; > +import org.junit.BeforeClass; > +import org.junit.Test; > + > +public class TestImpersonationWithHadoopAuth extends > SolrCloudTestCase { > + protected static final int NUM_SERVERS = 2; > + private static final boolean defaultAddRequestHeadersToContext = > + SolrRequestParsers.DEFAULT.isAddRequestHeadersToContext(); > + > + @SuppressWarnings("unchecked") > + @BeforeClass > + public static void setupClass() throws Exception { > + assumeFalse("Hadoop does not work on Windows", > Constants.WINDOWS); > + > + InetAddress loopback = InetAddress.getLoopbackAddress(); > + Path securityJsonPath = > TEST_PATH().resolve("security").resolve("hadoop_simple_auth_with_delegat > ion.json"); > + String securityJson = new String(Files.readAllBytes(securityJsonPath), > Charset.defaultCharset()); > + > + Map<String, Object> securityConfig = (Map<String, > Object>)Utils.fromJSONString(securityJson); > + Map<String, Object> authConfig = (Map<String, > Object>)securityConfig.get("authentication"); > + Map<String,String> proxyUserConfigs = (Map<String,String>) authConfig > + .getOrDefault(HadoopAuthPlugin.PROXY_USER_CONFIGS, new > HashMap<>()); > + proxyUserConfigs.put("proxyuser.noGroups.hosts", "*"); > + proxyUserConfigs.put("proxyuser.anyHostAnyUser.hosts", "*"); > + proxyUserConfigs.put("proxyuser.anyHostAnyUser.groups", "*"); > + proxyUserConfigs.put("proxyuser.wrongHost.hosts", "1.1.1.1.1.1"); > + proxyUserConfigs.put("proxyuser.wrongHost.groups", "*"); > + proxyUserConfigs.put("proxyuser.noHosts.groups", "*"); > + proxyUserConfigs.put("proxyuser.localHostAnyGroup.hosts", > + loopback.getCanonicalHostName() + "," + loopback.getHostName() + "," > + loopback.getHostAddress()); > + proxyUserConfigs.put("proxyuser.localHostAnyGroup.groups", "*"); > + proxyUserConfigs.put("proxyuser.bogusGroup.hosts", "*"); > + proxyUserConfigs.put("proxyuser.bogusGroup.groups", > "__some_bogus_group"); > + proxyUserConfigs.put("proxyuser.anyHostUsersGroup.groups", > ImpersonationUtil.getUsersFirstGroup()); > + proxyUserConfigs.put("proxyuser.anyHostUsersGroup.hosts", "*"); > + > + authConfig.put(HadoopAuthPlugin.PROXY_USER_CONFIGS, > proxyUserConfigs); > + > + SolrRequestParsers.DEFAULT.setAddRequestHeadersToContext(true); > + System.setProperty("collectionsHandler", > ImpersonatorCollectionsHandler.class.getName()); > + > + configureCluster(NUM_SERVERS)// nodes > + .withSecurityJson(Utils.toJSONString(securityConfig)) > + .addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud- > minimal").resolve("conf")) > + .configure(); > + } > + > + @AfterClass > + public static void tearDownClass() throws Exception { > + > SolrRequestParsers.DEFAULT.setAddRequestHeadersToContext(defaultAddR > equestHeadersToContext); > + System.clearProperty("collectionsHandler"); > + } > + > + private SolrClient newSolrClient() { > + return new HttpSolrClient.Builder( > + cluster.getJettySolrRunner(0).getBaseUrl().toString()).build(); > + } > + > + @Test > + public void testProxyNoConfigGroups() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("noGroups","bar")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + assertTrue(ex.getLocalizedMessage(), > ex.getMessage().contains(getExpectedGroupExMsg("noGroups", "bar"))); > + } > + } > + > + @Test > + public void testProxyWrongHost() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("wrongHost","bar")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + > assertTrue(ex.getMessage().contains(getExpectedHostExMsg("wrongHost"))) > ; > + } > + } > + > + @Test > + public void testProxyNoConfigHosts() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("noHosts","bar")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + > assertTrue(ex.getMessage().contains(getExpectedHostExMsg("noHosts"))); > + } > + } > + > + @Test > + public void testProxyValidateAnyHostAnyUser() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("anyHostAnyUser", "bar")); > + assertTrue(ImpersonatorCollectionsHandler.called.get()); > + } > + } > + > + @Test > + public void testProxyInvalidProxyUser() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + // wrong direction, should fail > + solrClient.request(getProxyRequest("bar","anyHostAnyUser")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + assertTrue(ex.getMessage().contains(getExpectedGroupExMsg("bar", > "anyHostAnyUser"))); > + } > + } > + > + @Test > + public void testProxyValidateHost() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("localHostAnyGroup", "bar")); > + assertTrue(ImpersonatorCollectionsHandler.called.get()); > + } > + } > + > + @Test > + public void testProxyValidateGroup() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("anyHostUsersGroup", > System.getProperty("user.name"))); > + assertTrue(ImpersonatorCollectionsHandler.called.get()); > + } > + } > + > + @Test > + public void testProxyInvalidGroup() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("bogusGroup","bar")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + > assertTrue(ex.getMessage().contains(getExpectedGroupExMsg("bogusGroup > ", "bar"))); > + } > + } > + > + @Test > + public void testProxyNullProxyUser() throws Exception { > + try (SolrClient solrClient = newSolrClient()) { > + solrClient.request(getProxyRequest("","bar")); > + fail("Expected RemoteSolrException"); > + } > + catch (HttpSolrClient.RemoteSolrException ex) { > + // this exception is specific to our implementation, don't check a > specific > message. > + } > + } > + > + @Test > + @AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/HADOOP- > 9893") > + public void testForwarding() throws Exception { > + String collectionName = "forwardingCollection"; > + > + // create collection > + CollectionAdminRequest.Create create = > CollectionAdminRequest.createCollection(collectionName, "conf1", > + 1, 1); > + try (SolrClient solrClient = newSolrClient()) { > + create.process(solrClient); > + } > + > + // try a command to each node, one of them must be forwarded > + for (JettySolrRunner jetty : cluster.getJettySolrRunners()) { > + HttpSolrClient client = > + new HttpSolrClient.Builder(jetty.getBaseUrl().toString() + "/" + > collectionName).build(); > + try { > + ModifiableSolrParams params = new ModifiableSolrParams(); > + params.set("q", "*:*"); > + params.set(USER_PARAM, "user"); > + client.query(params); > + } finally { > + client.close(); > + } > + } > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/core/src/test/org/apache/solr/security/hadoop/Te > stSolrCloudWithHadoopAuthPlugin.java > ---------------------------------------------------------------------- > diff --git > a/solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHa > doopAuthPlugin.java > b/solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHa > doopAuthPlugin.java > new file mode 100644 > index 0000000..960fd9a > --- /dev/null > +++ > b/solr/core/src/test/org/apache/solr/security/hadoop/TestSolrCloudWithHa > doopAuthPlugin.java > @@ -0,0 +1,136 @@ > +/* > + * 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.security.hadoop; > + > +import java.io.File; > +import java.nio.charset.StandardCharsets; > + > +import org.apache.commons.io.FileUtils; > +import org.apache.lucene.util.Constants; > +import org.apache.solr.client.solrj.SolrQuery; > +import org.apache.solr.client.solrj.impl.CloudSolrClient; > +import org.apache.solr.client.solrj.request.CollectionAdminRequest; > +import org.apache.solr.client.solrj.response.QueryResponse; > +import org.apache.solr.cloud.AbstractDistribZkTestBase; > +import org.apache.solr.cloud.KerberosTestServices; > +import org.apache.solr.cloud.SolrCloudTestCase; > +import org.apache.solr.common.SolrInputDocument; > +import org.junit.AfterClass; > +import org.junit.BeforeClass; > +import org.junit.Test; > + > +public class TestSolrCloudWithHadoopAuthPlugin extends > SolrCloudTestCase { > + protected static final int NUM_SERVERS = 1; > + protected static final int NUM_SHARDS = 1; > + protected static final int REPLICATION_FACTOR = 1; > + private static KerberosTestServices kerberosTestServices; > + > + @BeforeClass > + public static void setupClass() throws Exception { > + assumeFalse("Hadoop does not work on Windows", > Constants.WINDOWS); > + assumeFalse("FIXME: SOLR-8182: This test fails under Java 9", > Constants.JRE_IS_MINIMUM_JAVA9); > + > + setupMiniKdc(); > + > + configureCluster(NUM_SERVERS)// nodes > + > .withSecurityJson(TEST_PATH().resolve("security").resolve("hadoop_kerbero > s_config.json")) > + .addConfig("conf1", TEST_PATH().resolve("configsets").resolve("cloud- > minimal").resolve("conf")) > + .configure(); > + } > + > + @AfterClass > + public static void tearDownClass() throws Exception { > + System.clearProperty("java.security.auth.login.config"); > + System.clearProperty("solr.kerberos.principal"); > + System.clearProperty("solr.kerberos.keytab"); > + System.clearProperty("solr.kerberos.name.rules"); > + System.clearProperty("solr.jaas.debug"); > + kerberosTestServices.stop(); > + kerberosTestServices = null; > + } > + > + private static void setupMiniKdc() throws Exception { > + System.setProperty("solr.jaas.debug", "true"); > + String kdcDir = createTempDir()+File.separator+"minikdc"; > + String solrClientPrincipal = "solr"; > + File keytabFile = new File(kdcDir, "keytabs"); > + kerberosTestServices = KerberosTestServices.builder() > + .withKdc(new File(kdcDir)) > + .withJaasConfiguration(solrClientPrincipal, keytabFile, "SolrClient") > + .build(); > + String solrServerPrincipal = "HTTP/127.0.0.1"; > + kerberosTestServices.start(); > + kerberosTestServices.getKdc().createPrincipal(keytabFile, > solrServerPrincipal, solrClientPrincipal); > + > + String jaas = "SolrClient {\n" > + + " com.sun.security.auth.module.Krb5LoginModule required\n" > + + " useKeyTab=true\n" > + + " keyTab=\"" + keytabFile.getAbsolutePath() + "\"\n" > + + " storeKey=true\n" > + + " useTicketCache=false\n" > + + " doNotPrompt=true\n" > + + " debug=true\n" > + + " principal=\"" + solrClientPrincipal + "\";\n" > + + "};"; > + > + String jaasFilePath = kdcDir+File.separator+"jaas-client.conf"; > + FileUtils.write(new File(jaasFilePath), jaas, StandardCharsets.UTF_8); > + System.setProperty("java.security.auth.login.config", jaasFilePath); > + System.setProperty("solr.kerberos.jaas.appname", "SolrClient"); // Get > this app name from the jaas file > + > + System.setProperty("solr.kerberos.principal", solrServerPrincipal); > + System.setProperty("solr.kerberos.keytab", > keytabFile.getAbsolutePath()); > + // Extracts 127.0.0.1 from HTTP/[email protected] > + System.setProperty("solr.kerberos.name.rules", > "RULE:[1:$1@$0](.*EXAMPLE.COM)s/@.*//" > + + "\nRULE:[2:$2@$0](.*EXAMPLE.COM)s/@.*//" > + + "\nDEFAULT" > + ); > + } > + > + @Test > + public void testBasics() throws Exception { > + testCollectionCreateSearchDelete(); > + // sometimes run a second test e.g. to test collection > create-delete-create > scenario > + if (random().nextBoolean()) testCollectionCreateSearchDelete(); > + } > + > + protected void testCollectionCreateSearchDelete() throws Exception { > + CloudSolrClient solrClient = cluster.getSolrClient(); > + String collectionName = "testkerberoscollection"; > + > + // create collection > + CollectionAdminRequest.Create create = > CollectionAdminRequest.createCollection(collectionName, "conf1", > + NUM_SHARDS, REPLICATION_FACTOR); > + create.process(solrClient); > + > + SolrInputDocument doc = new SolrInputDocument(); > + doc.setField("id", "1"); > + solrClient.add(collectionName, doc); > + solrClient.commit(collectionName); > + > + SolrQuery query = new SolrQuery(); > + query.setQuery("*:*"); > + QueryResponse rsp = solrClient.query(collectionName, query); > + assertEquals(1, rsp.getResults().getNumFound()); > + > + CollectionAdminRequest.Delete deleteReq = > CollectionAdminRequest.deleteCollection(collectionName); > + deleteReq.process(solrClient); > + AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName, > + solrClient.getZkStateReader(), true, true, 330); > + } > + > +} > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Htt > pClientBuilderFactory.java > ---------------------------------------------------------------------- > diff --git > a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFact > ory.java > b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFact > ory.java > new file mode 100644 > index 0000000..77c4a94 > --- /dev/null > +++ > b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/HttpClientBuilderFact > ory.java > @@ -0,0 +1,41 @@ > +/* > + * 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 java.io.Closeable; > +import java.util.Optional; > + > +/** > + * Factory interface for configuring {@linkplain SolrHttpClientBuilder}. This > + * relies on the internal HttpClient implementation and is subject to > + * change. > + * > + * @lucene.experimental > + **/ > +public interface HttpClientBuilderFactory extends Closeable { > + > + /** > + * This method configures the {@linkplain SolrHttpClientBuilder} by > overriding the > + * configuration of passed SolrHttpClientBuilder or as a new instance. > + * > + * @param builder The instance of the {@linkplain SolrHttpClientBuilder} > which should > + * by configured (optional). > + * @return the {@linkplain SolrHttpClientBuilder} > + */ > + public SolrHttpClientBuilder > getHttpClientBuilder(Optional<SolrHttpClientBuilder> builder); > + > +} > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Kr > b5HttpClientBuilder.java > ---------------------------------------------------------------------- > diff --git > a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientBuilder > .java > b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientBuilder > .java > index 39cc2dc..7f3cf29 100644 > --- > a/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientBuilder > .java > +++ > b/solr/solrj/src/java/org/apache/solr/client/solrj/impl/Krb5HttpClientBuilder > .java > @@ -21,6 +21,7 @@ import java.security.Principal; > import java.util.Arrays; > import java.util.HashSet; > import java.util.Locale; > +import java.util.Optional; > import java.util.Set; > > import javax.security.auth.login.AppConfigurationEntry; > @@ -46,7 +47,7 @@ import org.slf4j.LoggerFactory; > /** > * Kerberos-enabled SolrHttpClientBuilder > */ > -public class Krb5HttpClientBuilder { > +public class Krb5HttpClientBuilder implements HttpClientBuilderFactory { > > public static final String LOGIN_CONFIG_PROP = > "java.security.auth.login.config"; > private static final Logger logger = > LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); > @@ -73,7 +74,12 @@ public class Krb5HttpClientBuilder { > public void close() { > HttpClientUtil.removeRequestInterceptor(bufferedEntityInterceptor); > } > - > + > + @Override > + public SolrHttpClientBuilder > getHttpClientBuilder(Optional<SolrHttpClientBuilder> builder) { > + return builder.isPresent() ? getBuilder(builder.get()) : getBuilder(); > + } > + > public SolrHttpClientBuilder getBuilder(SolrHttpClientBuilder builder) { > if (System.getProperty(LOGIN_CONFIG_PROP) != null) { > String configValue = System.getProperty(LOGIN_CONFIG_PROP); > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/test- > framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java > ---------------------------------------------------------------------- > diff --git a/solr/test- > framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java > b/solr/test- > framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java > index 5ebdfb7..81e1f22 100644 > --- a/solr/test- > framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java > +++ b/solr/test- > framework/src/java/org/apache/solr/cloud/MiniSolrCloudCluster.java > @@ -28,6 +28,7 @@ import java.util.Collection; > import java.util.Collections; > import java.util.List; > import java.util.Objects; > +import java.util.Optional; > import java.util.Random; > import java.util.SortedMap; > import java.util.concurrent.Callable; > @@ -68,6 +69,7 @@ public class MiniSolrCloudCluster { > " <str name=\"shareSchema\">${shareSchema:false}</str>\n" + > " <str > name=\"configSetBaseDir\">${configSetBaseDir:configsets}</str>\n" + > " <str name=\"coreRootDirectory\">${coreRootDirectory:.}</str>\n" + > + " <str > name=\"collectionsHandler\">${collectionsHandler:solr.CollectionsHandler}< > /str>\n" + > "\n" + > " <shardHandlerFactory name=\"shardHandlerFactory\" > class=\"HttpShardHandlerFactory\">\n" + > " <str name=\"urlScheme\">${urlScheme:}</str>\n" + > @@ -180,8 +182,30 @@ public class MiniSolrCloudCluster { > * > * @throws Exception if there was an error starting the cluster > */ > - public MiniSolrCloudCluster(int numServers, Path baseDir, String solrXml, > JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception { > + public MiniSolrCloudCluster(int numServers, Path baseDir, String solrXml, > JettyConfig jettyConfig, > + ZkTestServer zkTestServer) throws Exception { > + this(numServers, baseDir, solrXml, jettyConfig, zkTestServer, > Optional.empty()); > + } > > + /** > + * Create a MiniSolrCloudCluster. > + * Note - this constructor visibility is changed to package protected so > as to > + * discourage its usage. Ideally *new* functionality should use {@linkplain > SolrCloudTestCase} > + * to configure any additional parameters. > + * > + * @param numServers number of Solr servers to start > + * @param baseDir base directory that the mini cluster should be run from > + * @param solrXml solr.xml file to be uploaded to ZooKeeper > + * @param jettyConfig Jetty configuration > + * @param zkTestServer ZkTestServer to use. If null, one will be created > + * @param securityJson A string representation of security.json file > (optional). > + * > + * @throws Exception if there was an error starting the cluster > + */ > + MiniSolrCloudCluster(int numServers, Path baseDir, String solrXml, > JettyConfig jettyConfig, > + ZkTestServer zkTestServer, Optional<String> securityJson) throws > Exception { > + > + Objects.requireNonNull(securityJson); > this.baseDir = Objects.requireNonNull(baseDir); > this.jettyConfig = Objects.requireNonNull(jettyConfig); > > @@ -202,6 +226,9 @@ public class MiniSolrCloudCluster { > if (jettyConfig.sslConfig != null && > jettyConfig.sslConfig.isSSLMode()) { > zkClient.makePath("/solr" + ZkStateReader.CLUSTER_PROPS, > "{'urlScheme':'https'}".getBytes(StandardCharsets.UTF_8), true); > } > + if (securityJson.isPresent()) { // configure Solr security > + zkClient.makePath("/solr/security.json", > securityJson.get().getBytes(Charset.defaultCharset()), true); > + } > } > > // tell solr to look in zookeeper for solr.xml > > http://git-wip-us.apache.org/repos/asf/lucene- > solr/blob/a1a8b286/solr/test- > framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java > ---------------------------------------------------------------------- > diff --git a/solr/test- > framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java > b/solr/test- > framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java > index 9cc4a22..34dc8ac 100644 > --- a/solr/test- > framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java > +++ b/solr/test- > framework/src/java/org/apache/solr/cloud/SolrCloudTestCase.java > @@ -26,6 +26,7 @@ import java.util.Collections; > import java.util.HashMap; > import java.util.List; > import java.util.Map; > +import java.util.Optional; > import java.util.concurrent.TimeUnit; > import java.util.concurrent.atomic.AtomicReference; > import java.util.function.Predicate; > @@ -90,6 +91,7 @@ public class SolrCloudTestCase extends SolrTestCaseJ4 { > private final Path baseDir; > private String solrxml = > MiniSolrCloudCluster.DEFAULT_CLOUD_SOLR_XML; > private JettyConfig jettyConfig = buildJettyConfig("/solr"); > + private Optional<String> securityJson = Optional.empty(); > > private List<Config> configs = new ArrayList<>(); > private Map<String, String> clusterProperties = new HashMap<>(); > @@ -133,6 +135,32 @@ public class SolrCloudTestCase extends > SolrTestCaseJ4 { > } > > /** > + * Configure the specified security.json for the {@linkplain > MiniSolrCloudCluster} > + * > + * @param securityJson The path specifying the security.json file > + * @return the instance of {@linkplain Builder} > + */ > + public Builder withSecurityJson(Path securityJson) { > + try { > + this.securityJson = Optional.of(new > String(Files.readAllBytes(securityJson), Charset.defaultCharset())); > + } catch (IOException e) { > + throw new RuntimeException(e); > + } > + return this; > + } > + > + /** > + * Configure the specified security.json for the {@linkplain > MiniSolrCloudCluster} > + * > + * @param securityJson The string specifying the security.json > configuration > + * @return the instance of {@linkplain Builder} > + */ > + public Builder withSecurityJson(String securityJson) { > + this.securityJson = Optional.of(securityJson); > + return this; > + } > + > + /** > * Upload a collection config before tests start > * @param configName the config name > * @param configPath the path to the config files > @@ -157,7 +185,7 @@ public class SolrCloudTestCase extends > SolrTestCaseJ4 { > * @throws Exception if an error occurs on startup > */ > public void configure() throws Exception { > - cluster = new MiniSolrCloudCluster(nodeCount, baseDir, solrxml, > jettyConfig); > + cluster = new MiniSolrCloudCluster(nodeCount, baseDir, solrxml, > jettyConfig, null, securityJson); > CloudSolrClient client = cluster.getSolrClient(); > for (Config config : configs) { > > ((ZkClientClusterStateProvider)client.getClusterStateProvider()).uploadConfig > (config.path, config.name); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
