SOLR-8221: MiniSolrCloudCluster creates subdirectories for its child nodes

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1711041 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Alan Woodward 2015-10-28 15:43:51 +00:00
parent 77f7614a46
commit cb234d3c6b
16 changed files with 225 additions and 236 deletions

View File

@ -396,6 +396,9 @@ Other Changes
* SOLR-8196: TestMiniSolrCloudCluster.testStopAllStartAll case plus necessary
MiniSolrCloudCluster tweak (Christine Poerschke)
* SOLR-8221: MiniSolrCloudCluster should create subdirectories for its nodes
(Alan Woodward)
================== 5.3.1 ==================
Bug Fixes

View File

@ -43,8 +43,7 @@ public class ConcurrentDeleteAndCreateCollectionTest extends SolrTestCaseJ4 {
@Before
public void setUp() throws Exception {
super.setUp();
final File solrXml = getFile("solr").toPath().resolve("solr.xml").toFile();
solrCluster = new MiniSolrCloudCluster(1, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
solrCluster = new MiniSolrCloudCluster(1, createTempDir());
}
@Override

View File

@ -84,20 +84,17 @@ public class TestAuthenticationFramework extends TestMiniSolrCloudCluster {
}
@Test
@Override
public void testBasics() throws Exception {
final String collectionName = "testAuthenticationFrameworkCollection";
// Should pass
testCollectionCreateSearchDelete(collectionName);
testCollectionCreateSearchDelete();
MockAuthenticationPlugin.expectedUsername = "solr";
MockAuthenticationPlugin.expectedPassword = "s0lrRocks";
// Should fail with 401
try {
testCollectionCreateSearchDelete(collectionName);
testCollectionCreateSearchDelete();
fail("Should've returned a 401 error");
} catch (Exception ex) {
if (!ex.getMessage().contains("Error 401")) {

View File

@ -17,7 +17,6 @@
package org.apache.solr.cloud;
import com.google.common.collect.ImmutableMap;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.InputStreamReader;
@ -29,6 +28,7 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.FileUtils;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrClient;
@ -48,11 +48,11 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.ConfigSetProperties;
import org.apache.zookeeper.KeeperException;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import static org.apache.solr.cloud.OverseerConfigSetMessageHandler.BASE_CONFIGSET;
import static org.apache.solr.common.params.CommonParams.NAME;
import static org.apache.solr.core.ConfigSetProperties.DEFAULT_FILENAME;
@ -68,8 +68,7 @@ public class TestConfigSetsAPI extends SolrTestCaseJ4 {
@Before
public void setUp() throws Exception {
super.setUp();
final File solrXml = getFile("solr").toPath().resolve("solr.xml").toFile();
solrCluster = new MiniSolrCloudCluster(1, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
solrCluster = new MiniSolrCloudCluster(1, createTempDir(), buildJettyConfig("/solr"));
}
@Override

View File

@ -56,10 +56,7 @@ public class TestConfigSetsAPIExclusivity extends SolrTestCaseJ4 {
@Before
public void setUp() throws Exception {
super.setUp();
final File solrXml = getFile("solr").toPath().resolve("solr.xml").toFile();
final File testDir = createTempDir().toFile();
solrCluster = new MiniSolrCloudCluster(1, testDir,
solrXml, buildJettyConfig("/solr"));
solrCluster = new MiniSolrCloudCluster(1, createTempDir(), buildJettyConfig("/solr"));
}
@Override

View File

@ -17,11 +17,11 @@
package org.apache.solr.cloud;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
@ -30,6 +30,7 @@ import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.FileUtils;
import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
@ -40,7 +41,6 @@ import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException;
import org.apache.solr.client.solrj.request.ConfigSetAdminRequest.Create;
import org.apache.solr.client.solrj.response.ConfigSetAdminResponse;
import org.apache.solr.cloud.ZkTestServer;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkConfigManager;
@ -51,15 +51,14 @@ import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.quorum.Leader.Proposal;
import org.apache.zookeeper.server.DataNode;
import org.apache.zookeeper.server.DataTree;
import org.apache.zookeeper.server.DataTree.ProcessTxnResult;
import org.apache.zookeeper.server.Request;
import org.apache.zookeeper.server.ServerCnxn;
import org.apache.zookeeper.server.ZKDatabase;
import org.apache.zookeeper.server.quorum.Leader.Proposal;
import org.apache.zookeeper.txn.TxnHeader;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
@ -82,16 +81,13 @@ public class TestConfigSetsAPIZkFailure extends SolrTestCaseJ4 {
@Before
public void setUp() throws Exception {
super.setUp();
final File solrXml = getFile("solr").toPath().resolve("solr.xml").toFile();
final File testDir = createTempDir().toFile();
String zkDir = testDir.getAbsolutePath() + File.separator
+ "zookeeper/server1/data";
final Path testDir = createTempDir();
String zkDir = testDir.resolve("zookeeper/server1/data").toString();
zkTestServer = new ZkTestServer(zkDir);
zkTestServer.run();
zkTestServer.setZKDatabase(
new FailureDuringCopyZKDatabase(zkTestServer.getZKDatabase(), zkTestServer));
zkTestServer.setZKDatabase(new FailureDuringCopyZKDatabase(zkTestServer.getZKDatabase(), zkTestServer));
solrCluster = new MiniSolrCloudCluster(1, testDir,
solrXml, buildJettyConfig("/solr"), zkTestServer);
MiniSolrCloudCluster.DEFAULT_CLOUD_SOLR_XML, buildJettyConfig("/solr"), zkTestServer);
}
@Override

View File

@ -34,13 +34,11 @@ import org.apache.lucene.util.LuceneTestCase;
import org.apache.lucene.util.LuceneTestCase.SuppressSysoutChecks;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.embedded.JettyConfig.Builder;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
@ -84,33 +82,11 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
public static TestRule solrClassRules = RuleChain.outerRule(
new SystemPropertiesRestoreRule()).around(
new RevertDefaultThreadHandlerRule());
@Test
public void testBasics() throws Exception {
final String collectionName = "testSolrCloudCollection";
testCollectionCreateSearchDelete(collectionName);
// sometimes run a second test e.g. to test collection create-delete-create scenario
if (random().nextBoolean()) testCollectionCreateSearchDelete(collectionName);
}
private MiniSolrCloudCluster createMiniSolrCloudCluster() throws Exception {
return createMiniSolrCloudCluster(false);
}
private MiniSolrCloudCluster createMiniSolrCloudCluster(boolean multipleBaseDirs) throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
Builder jettyConfig = JettyConfig.builder();
jettyConfig.waitForLoadingCoresToFinish(null);
if (multipleBaseDirs) {
final File baseDirs[] = new File[NUM_SERVERS];
for (int ii = 0; ii < NUM_SERVERS; ++ii) {
baseDirs[ii] = createTempDir().toFile();
}
return new MiniSolrCloudCluster(baseDirs, solrXml, jettyConfig.build(), null);
} else {
return new MiniSolrCloudCluster(NUM_SERVERS, createTempDir().toFile(), solrXml, jettyConfig.build());
}
return new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), jettyConfig.build());
}
private void createCollection(MiniSolrCloudCluster miniCluster, String collectionName, String createNodeSet, String asyncId, boolean persistIndex) throws Exception {
@ -129,9 +105,11 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
miniCluster.createCollection(collectionName, NUM_SHARDS, REPLICATION_FACTOR, configName, createNodeSet, asyncId, collectionProperties);
}
protected void testCollectionCreateSearchDelete(String collectionName) throws Exception {
@Test
public void testCollectionCreateSearchDelete() throws Exception {
final String collectionName = "testcollection";
MiniSolrCloudCluster miniCluster = createMiniSolrCloudCluster();
final CloudSolrClient cloudSolrClient = miniCluster.getSolrClient();
@ -145,85 +123,92 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
}
// shut down a server
log.info("#### Stopping a server");
JettySolrRunner stoppedServer = miniCluster.stopJettySolrRunner(0);
assertTrue(stoppedServer.isStopped());
assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
// create a server
log.info("#### Starting a server");
JettySolrRunner startedServer = miniCluster.startJettySolrRunner();
assertTrue(startedServer.isRunning());
assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
// create collection
log.info("#### Creating a collection");
final String asyncId = (random().nextBoolean() ? null : "asyncId("+collectionName+".create)="+random().nextInt());
createCollection(miniCluster, collectionName, null, asyncId, random().nextBoolean());
if (asyncId != null) {
assertEquals("did not see async createCollection completion", "completed", AbstractFullDistribZkTestBase.getRequestStateAfterCompletion(asyncId, 330, cloudSolrClient));
}
try (SolrZkClient zkClient = new SolrZkClient
(miniCluster.getZkServer().getZkAddress(), AbstractZkTestCase.TIMEOUT, 45000, null);
ZkStateReader zkStateReader = new ZkStateReader(zkClient)) {
AbstractDistribZkTestBase.waitForRecoveriesToFinish(collectionName, zkStateReader, true, true, 330);
ZkStateReader zkStateReader = miniCluster.getSolrClient().getZkStateReader();
AbstractDistribZkTestBase.waitForRecoveriesToFinish(collectionName, zkStateReader, true, true, 330);
// modify/query collection
cloudSolrClient.setDefaultCollection(collectionName);
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id", "1");
cloudSolrClient.add(doc);
cloudSolrClient.commit();
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
QueryResponse rsp = cloudSolrClient.query(query);
assertEquals(1, rsp.getResults().getNumFound());
// modify/query collection
log.info("#### updating a querying collection");
cloudSolrClient.setDefaultCollection(collectionName);
SolrInputDocument doc = new SolrInputDocument();
doc.setField("id", "1");
cloudSolrClient.add(doc);
cloudSolrClient.commit();
SolrQuery query = new SolrQuery();
query.setQuery("*:*");
QueryResponse rsp = cloudSolrClient.query(query);
assertEquals(1, rsp.getResults().getNumFound());
// remove a server not hosting any replicas
zkStateReader.updateClusterState();
ClusterState clusterState = zkStateReader.getClusterState();
HashMap<String, JettySolrRunner> jettyMap = new HashMap<String, JettySolrRunner>();
for (JettySolrRunner jetty : miniCluster.getJettySolrRunners()) {
String key = jetty.getBaseUrl().toString().substring((jetty.getBaseUrl().getProtocol() + "://").length());
jettyMap.put(key, jetty);
}
Collection<Slice> slices = clusterState.getSlices(collectionName);
// track the servers not host repliacs
for (Slice slice : slices) {
jettyMap.remove(slice.getLeader().getNodeName().replace("_solr", "/solr"));
for (Replica replica : slice.getReplicas()) {
jettyMap.remove(replica.getNodeName().replace("_solr", "/solr"));
}
}
assertTrue("Expected to find a node without a replica", jettyMap.size() > 0);
JettySolrRunner jettyToStop = jettyMap.entrySet().iterator().next().getValue();
jettys = miniCluster.getJettySolrRunners();
for (int i = 0; i < jettys.size(); ++i) {
if (jettys.get(i).equals(jettyToStop)) {
miniCluster.stopJettySolrRunner(i);
assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
}
}
// now restore the original state so that this function could be called multiple times
// re-create a server (to restore original NUM_SERVERS count)
startedServer = miniCluster.startJettySolrRunner();
assertTrue(startedServer.isRunning());
assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
Thread.sleep(15000);
try {
cloudSolrClient.query(query);
fail("Expected exception on query because collection should not be ready - we have turned on async core loading");
} catch (SolrServerException e) {
SolrException rc = (SolrException) e.getRootCause();
assertTrue(rc.code() >= 500 && rc.code() < 600);
} catch (SolrException e) {
assertTrue(e.code() >= 500 && e.code() < 600);
}
// delete the collection we created earlier
miniCluster.deleteCollection(collectionName);
AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName, zkStateReader, true, true, 330);
// remove a server not hosting any replicas
zkStateReader.updateClusterState();
ClusterState clusterState = zkStateReader.getClusterState();
HashMap<String, JettySolrRunner> jettyMap = new HashMap<String, JettySolrRunner>();
for (JettySolrRunner jetty : miniCluster.getJettySolrRunners()) {
String key = jetty.getBaseUrl().toString().substring((jetty.getBaseUrl().getProtocol() + "://").length());
jettyMap.put(key, jetty);
}
Collection<Slice> slices = clusterState.getSlices(collectionName);
// track the servers not host repliacs
for (Slice slice : slices) {
jettyMap.remove(slice.getLeader().getNodeName().replace("_solr", "/solr"));
for (Replica replica : slice.getReplicas()) {
jettyMap.remove(replica.getNodeName().replace("_solr", "/solr"));
}
}
assertTrue("Expected to find a node without a replica", jettyMap.size() > 0);
log.info("#### Stopping a server");
JettySolrRunner jettyToStop = jettyMap.entrySet().iterator().next().getValue();
jettys = miniCluster.getJettySolrRunners();
for (int i = 0; i < jettys.size(); ++i) {
if (jettys.get(i).equals(jettyToStop)) {
miniCluster.stopJettySolrRunner(i);
assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
}
}
// re-create a server (to restore original NUM_SERVERS count)
log.info("#### Starting a server");
startedServer = miniCluster.startJettySolrRunner(jettyToStop);
assertTrue(startedServer.isRunning());
assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
// delete the collection we created earlier
miniCluster.deleteCollection(collectionName);
AbstractDistribZkTestBase.waitForCollectionToDisappear(collectionName, zkStateReader, true, true, 330);
// create it again
String asyncId2 = (random().nextBoolean() ? null : "asyncId("+collectionName+".create)="+random().nextInt());
createCollection(miniCluster, collectionName, null, asyncId2, random().nextBoolean());
if (asyncId2 != null) {
assertEquals("did not see async createCollection completion", "completed", AbstractFullDistribZkTestBase.getRequestStateAfterCompletion(asyncId2, 330, cloudSolrClient));
}
AbstractDistribZkTestBase.waitForRecoveriesToFinish(collectionName, zkStateReader, true, true, 330);
// check that there's no left-over state
assertEquals(0, cloudSolrClient.query(new SolrQuery("*:*")).getResults().getNumFound());
cloudSolrClient.add(doc);
cloudSolrClient.commit();
assertEquals(1, cloudSolrClient.query(new SolrQuery("*:*")).getResults().getNumFound());
}
finally {
miniCluster.shutdown();
@ -233,16 +218,15 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
@Test
public void testErrorsInStartup() throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
AtomicInteger jettyIndex = new AtomicInteger();
MiniSolrCloudCluster cluster = null;
try {
cluster = new MiniSolrCloudCluster(3, createTempDir().toFile(), solrXml, JettyConfig.builder().build()) {
cluster = new MiniSolrCloudCluster(3, createTempDir(), JettyConfig.builder().build()) {
@Override
public JettySolrRunner startJettySolrRunner(JettyConfig config) throws Exception {
public JettySolrRunner startJettySolrRunner(String name, String context, JettyConfig config) throws Exception {
if (jettyIndex.incrementAndGet() != 2)
return super.startJettySolrRunner(config);
return super.startJettySolrRunner(name, context, config);
throw new IOException("Fake exception on startup!");
}
};
@ -262,10 +246,9 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
@Test
public void testErrorsInShutdown() throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
AtomicInteger jettyIndex = new AtomicInteger();
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(3, createTempDir().toFile(), solrXml, JettyConfig.builder().build()) {
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(3, createTempDir(), JettyConfig.builder().build()) {
@Override
protected JettySolrRunner stopJettySolrRunner(JettySolrRunner jetty) throws Exception {
JettySolrRunner j = super.stopJettySolrRunner(jetty);
@ -288,12 +271,11 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
}
@Test
public void testExraFilters() throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
public void testExtraFilters() throws Exception {
Builder jettyConfig = JettyConfig.builder();
jettyConfig.waitForLoadingCoresToFinish(null);
jettyConfig.withFilter(JettySolrRunner.DebugFilter.class, "*");
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir().toFile(), solrXml, jettyConfig.build());
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), jettyConfig.build());
cluster.shutdown();
}
@ -346,7 +328,7 @@ public class TestMiniSolrCloudCluster extends LuceneTestCase {
final String collectionName = "testStopAllStartAllCollection";
final MiniSolrCloudCluster miniCluster = createMiniSolrCloudCluster(true);
final MiniSolrCloudCluster miniCluster = createMiniSolrCloudCluster();
try {
assertNotNull(miniCluster.getZkServer());

View File

@ -28,12 +28,10 @@ import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule;
import org.apache.lucene.util.LuceneTestCase;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.CloudSolrClient;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.SolrInputDocument;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
@ -80,12 +78,9 @@ public class TestMiniSolrCloudClusterBase extends LuceneTestCase {
}
private MiniSolrCloudCluster createMiniSolrCloudCluster() throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
JettyConfig.Builder jettyConfig = JettyConfig.builder();
jettyConfig.waitForLoadingCoresToFinish(null);
MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir().toFile(), solrXml, jettyConfig.build());
return miniCluster;
return new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), jettyConfig.build());
}
private void createCollection(MiniSolrCloudCluster miniCluster, String collectionName, String createNodeSet, String asyncId) throws Exception {
@ -184,16 +179,6 @@ public class TestMiniSolrCloudClusterBase extends LuceneTestCase {
startedServer = miniCluster.startJettySolrRunner();
assertTrue(startedServer.isRunning());
assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());
Thread.sleep(15000);
try {
cloudSolrClient.query(query);
fail("Expected exception on query because collection should not be ready - we have turned on async core loading");
} catch (SolrServerException e) {
SolrException rc = (SolrException) e.getRootCause();
assertTrue(rc.code() >= 500 && rc.code() < 600);
} catch (SolrException e) {
assertTrue(e.code() >= 500 && e.code() < 600);
}
doExtraTests(miniCluster, zkClient, zkStateReader,cloudSolrClient, collectionName);
}

View File

@ -131,11 +131,8 @@ public class TestMiniSolrCloudClusterKerberos extends TestMiniSolrCloudCluster {
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/HADOOP-9893")
@Test
@Override
public void testBasics() throws Exception {
final String collectionName = "testSolrCloudCollectionKerberos";
testCollectionCreateSearchDelete(collectionName);
// sometimes run a second test e.g. to test collection create-delete-create scenario
if (random().nextBoolean()) testCollectionCreateSearchDelete(collectionName);
public void testCollectionCreateSearchDelete() throws Exception {
super.testCollectionCreateSearchDelete();
}
@AwaitsFix(bugUrl="https://issues.apache.org/jira/browse/HADOOP-9893")

View File

@ -17,7 +17,10 @@ package org.apache.solr.cloud;
* limitations under the License.
*/
import java.util.List;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.embedded.JettyConfig;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.HttpSolrClient;
import org.apache.solr.client.solrj.request.CoreAdminRequest;
@ -26,9 +29,6 @@ import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.io.File;
import java.util.List;
/**
* Tests SSL (if test framework selects it) with MiniSolrCloudCluster.
* {@link TestMiniSolrCloudCluster} does not inherit from {@link SolrTestCaseJ4}
@ -41,9 +41,8 @@ public class TestMiniSolrCloudClusterSSL extends SolrTestCaseJ4 {
@BeforeClass
public static void startup() throws Exception {
String testHome = SolrTestCaseJ4.TEST_HOME();
miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, null, createTempDir().toFile(), new File(testHome, "solr-no-core.xml"),
null, null, sslConfig);
JettyConfig config = JettyConfig.builder().withSSLConfig(sslConfig).build();
miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir(), config);
}
@AfterClass
@ -65,7 +64,7 @@ public class TestMiniSolrCloudClusterSSL extends SolrTestCaseJ4 {
assertEquals(NUM_SERVERS - 1, miniCluster.getJettySolrRunners().size());
// create a new server
JettySolrRunner startedServer = miniCluster.startJettySolrRunner(null, null, null, sslConfig);
JettySolrRunner startedServer = miniCluster.startJettySolrRunner();
assertTrue(startedServer.isRunning());
assertEquals(NUM_SERVERS, miniCluster.getJettySolrRunners().size());

View File

@ -157,9 +157,8 @@ public class TestSolrCloudWithKerberosAlt extends LuceneTestCase {
protected void testCollectionCreateSearchDelete() throws Exception {
HttpClientUtil.setConfigurer(new Krb5HttpClientConfigurer());
String collectionName = "testkerberoscollection";
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, null, createTempDir().toFile(), solrXml, null, null);
MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir());
CloudSolrClient cloudSolrClient = miniCluster.getSolrClient();
cloudSolrClient.setDefaultCollection(collectionName);

View File

@ -174,9 +174,8 @@ public class PingRequestHandlerTest extends SolrTestCaseJ4 {
}
public void testPingInClusterWithNoHealthCheck() throws Exception {
File solrXml = new File(SolrTestCaseJ4.TEST_HOME(), "solr-no-core.xml");
MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
MiniSolrCloudCluster miniCluster = new MiniSolrCloudCluster(NUM_SERVERS, createTempDir());
final CloudSolrClient cloudSolrClient = miniCluster.getSolrClient();

View File

@ -52,8 +52,7 @@ public class TestDistribIDF extends SolrTestCaseJ4 {
}
super.setUp();
final File solrXml = getFile("solr").toPath().resolve("solr-no-core.xml").toFile();
solrCluster = new MiniSolrCloudCluster(3, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
solrCluster = new MiniSolrCloudCluster(3, createTempDir());
// set some system properties for use by tests
System.setProperty("solr.test.sys.prop1", "propone");
System.setProperty("solr.test.sys.prop2", "proptwo");

View File

@ -25,8 +25,11 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -95,9 +98,9 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
if (!hasFlag("-cloud", args) && !hasFlag("-c", args))
return startStandaloneSolr(args);
File baseDir = createTempDir().toFile();
File solrHomeDir = new File(getArg("-s", args));
String solrHomeDir = getArg("-s", args);
int port = Integer.parseInt(getArg("-p", args));
String solrxml = new String(Files.readAllBytes(Paths.get(solrHomeDir).resolve("solr.xml")), Charset.defaultCharset());
JettyConfig jettyConfig =
JettyConfig.builder().setContext("/solr").setPort(port).build();
@ -106,7 +109,7 @@ public class TestSolrCLIRunExample extends SolrTestCaseJ4 {
System.setProperty("host", "localhost");
System.setProperty("jetty.port", String.valueOf(port));
solrCloudCluster =
new MiniSolrCloudCluster(1, baseDir, new File(solrHomeDir, "solr.xml"), jettyConfig);
new MiniSolrCloudCluster(1, createTempDir(), solrxml, jettyConfig);
} else {
// another member of this cluster -- not supported yet, due to how MiniSolrCloudCluster works
throw new IllegalArgumentException("Only launching one SolrCloud node is supported by this test!");

View File

@ -17,6 +17,9 @@ package org.apache.solr.client.solrj.impl;
* limitations under the License.
*/
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.request.CollectionAdminRequest;
import org.apache.solr.cloud.MiniSolrCloudCluster;
@ -24,19 +27,13 @@ import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.ZkConfigManager;
import org.junit.Test;
import java.io.File;
import java.nio.file.Path;
import java.util.concurrent.TimeUnit;
public class TestCloudSolrClientConnections extends SolrTestCaseJ4 {
@Test
public void testCloudClientCanConnectAfterClusterComesUp() throws Exception {
// Start by creating a cluster with no jetties
File solrXml = getFile("solrj").toPath().resolve("solr/solr.xml").toFile();
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(0, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(0, createTempDir());
try {
CloudSolrClient client = cluster.getSolrClient();
@ -66,10 +63,9 @@ public class TestCloudSolrClientConnections extends SolrTestCaseJ4 {
@Test
public void testCloudClientUploads() throws Exception {
File solrXml = getFile("solrj").toPath().resolve("solr/solr.xml").toFile();
Path configPath = getFile("solrj").toPath().resolve("solr/configsets/configset-2/conf");
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(0, createTempDir().toFile(), solrXml, buildJettyConfig("/solr"));
MiniSolrCloudCluster cluster = new MiniSolrCloudCluster(0, createTempDir());
try {
CloudSolrClient client = cluster.getSolrClient();
try {

View File

@ -17,6 +17,26 @@ package org.apache.solr.cloud;
* limitations under the License.
*/
import javax.servlet.Filter;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import com.google.common.base.Charsets;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettyConfig;
@ -36,43 +56,75 @@ import org.apache.solr.common.util.NamedList;
import org.apache.solr.common.util.SolrjNamedThreadFactory;
import org.apache.zookeeper.KeeperException;
import org.eclipse.jetty.servlet.ServletHolder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.servlet.Filter;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
/**
* "Mini" SolrCloud cluster to be used for testing
*/
public class MiniSolrCloudCluster {
private static Logger log = LoggerFactory.getLogger(MiniSolrCloudCluster.class);
public static final String DEFAULT_CLOUD_SOLR_XML = "<solr>\n" +
"\n" +
" <str name=\"shareSchema\">${shareSchema:false}</str>\n" +
" <str name=\"configSetBaseDir\">${configSetBaseDir:configsets}</str>\n" +
" <str name=\"coreRootDirectory\">${coreRootDirectory:.}</str>\n" +
"\n" +
" <shardHandlerFactory name=\"shardHandlerFactory\" class=\"HttpShardHandlerFactory\">\n" +
" <str name=\"urlScheme\">${urlScheme:}</str>\n" +
" <int name=\"socketTimeout\">${socketTimeout:90000}</int>\n" +
" <int name=\"connTimeout\">${connTimeout:15000}</int>\n" +
" </shardHandlerFactory>\n" +
"\n" +
" <solrcloud>\n" +
" <str name=\"host\">127.0.0.1</str>\n" +
" <int name=\"hostPort\">${hostPort:8983}</int>\n" +
" <str name=\"hostContext\">${hostContext:solr}</str>\n" +
" <int name=\"zkClientTimeout\">${solr.zkclienttimeout:30000}</int>\n" +
" <bool name=\"genericCoreNodeNames\">${genericCoreNodeNames:true}</bool>\n" +
" <int name=\"leaderVoteWait\">10000</int>\n" +
" <int name=\"distribUpdateConnTimeout\">${distribUpdateConnTimeout:45000}</int>\n" +
" <int name=\"distribUpdateSoTimeout\">${distribUpdateSoTimeout:340000}</int>\n" +
" </solrcloud>\n" +
" \n" +
"</solr>\n";
public static final JettyConfig DEFAULT_JETTY_CONFIG = JettyConfig.builder().setContext("/solr").build();
private final ZkTestServer zkServer;
private final boolean externalZkServer;
private final List<JettySolrRunner> jettys = new LinkedList<>();
private final File testDir;
private final File testDirs[];
private final Path baseDir;
private final CloudSolrClient solrClient;
private final JettyConfig jettyConfig;
private final ExecutorService executor = ExecutorUtil.newMDCAwareCachedThreadPool(new SolrjNamedThreadFactory("jetty-launcher"));
private final AtomicInteger nodeIds = new AtomicInteger();
/**
* Create a MiniSolrCloudCluster with default configuration
*
* @param numServers number of Solr servers to start
* @param baseDir base directory that the mini cluster should be run from
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, Path baseDir) throws Exception {
this(numServers, baseDir, DEFAULT_CLOUD_SOLR_XML, DEFAULT_JETTY_CONFIG, null);
}
/**
* Create a MiniSolrCloudCluster with default solr.xml
*
* @param numServers number of Solr servers to start
* @param baseDir base directory that the mini cluster should be run from
* @param jettyConfig Jetty configuration
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, Path baseDir, JettyConfig jettyConfig) throws Exception {
this(numServers, baseDir, DEFAULT_CLOUD_SOLR_XML, jettyConfig, null);
}
/**
* Create a MiniSolrCloudCluster
*
@ -85,7 +137,7 @@ public class MiniSolrCloudCluster {
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, String hostContext, File baseDir, File solrXml,
public MiniSolrCloudCluster(int numServers, String hostContext, Path baseDir, String solrXml,
SortedMap<ServletHolder, String> extraServlets,
SortedMap<Class<? extends Filter>, String> extraRequestFilters) throws Exception {
this(numServers, hostContext, baseDir, solrXml, extraServlets, extraRequestFilters, null);
@ -104,7 +156,7 @@ public class MiniSolrCloudCluster {
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, String hostContext, File baseDir, File solrXml,
public MiniSolrCloudCluster(int numServers, String hostContext, Path baseDir, String solrXml,
SortedMap<ServletHolder, String> extraServlets,
SortedMap<Class<? extends Filter>, String> extraRequestFilters,
SSLConfig sslConfig) throws Exception {
@ -126,7 +178,7 @@ public class MiniSolrCloudCluster {
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, File baseDir, File solrXml, JettyConfig jettyConfig) throws Exception {
public MiniSolrCloudCluster(int numServers, Path baseDir, String solrXml, JettyConfig jettyConfig) throws Exception {
this(numServers, baseDir, solrXml, jettyConfig, null);
}
@ -141,24 +193,16 @@ public class MiniSolrCloudCluster {
*
* @throws Exception if there was an error starting the cluster
*/
public MiniSolrCloudCluster(int numServers, File baseDir, File solrXml, JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception {
this(numServers, baseDir, null, solrXml, jettyConfig, zkTestServer);
}
public MiniSolrCloudCluster(int numServers, Path baseDir, String solrXml, JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception {
public MiniSolrCloudCluster(File[] baseDirs, File solrXml, JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception {
this(baseDirs.length, null, baseDirs, solrXml, jettyConfig, zkTestServer);
}
private MiniSolrCloudCluster(int numServers, File baseDir, File[] baseDirs, File solrXml, JettyConfig jettyConfig, ZkTestServer zkTestServer) throws Exception {
this.testDir = baseDir;
this.testDirs = baseDirs;
this.baseDir = baseDir;
this.jettyConfig = jettyConfig;
Files.createDirectories(baseDir);
this.externalZkServer = zkTestServer != null;
if (!externalZkServer) {
String zkDir = (testDir != null ? testDir : testDirs[0]).getAbsolutePath() + File.separator
+ "zookeeper/server1/data";
String zkDir = baseDir.resolve("zookeeper/server1/data").toString();
zkTestServer = new ZkTestServer(zkDir);
zkTestServer.run();
}
@ -166,7 +210,7 @@ public class MiniSolrCloudCluster {
try(SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(),
AbstractZkTestCase.TIMEOUT, 45000, null)) {
zkClient.makePath("/solr/solr.xml", solrXml, false, true);
zkClient.makePath("/solr/solr.xml", solrXml.getBytes(Charset.defaultCharset()), true);
if (jettyConfig.sslConfig != null && jettyConfig.sslConfig.isSSLMode()) {
zkClient.makePath("/solr" + ZkStateReader.CLUSTER_PROPS, "{'urlScheme':'https'}".getBytes(Charsets.UTF_8), true);
}
@ -177,14 +221,10 @@ public class MiniSolrCloudCluster {
List<Callable<JettySolrRunner>> startups = new ArrayList<>(numServers);
for (int i = 0; i < numServers; ++i) {
final Integer testDirsIdx = new Integer(i);
startups.add(new Callable<JettySolrRunner>() {
@Override
public JettySolrRunner call() throws Exception {
if (testDir != null)
return startJettySolrRunner(jettyConfig);
else
return startJettySolrRunner(testDirsIdx, jettyConfig.context, jettyConfig);
return startJettySolrRunner(newNodeName(), jettyConfig.context, jettyConfig);
}
});
}
@ -227,6 +267,16 @@ public class MiniSolrCloudCluster {
solrClient = buildSolrClient();
}
private String newNodeName() {
return "node" + nodeIds.incrementAndGet();
}
private Path createInstancePath(String name) throws IOException {
Path instancePath = baseDir.resolve(name);
Files.createDirectory(instancePath);
return instancePath;
}
/**
* @return ZooKeeper server used by the MiniCluster
*/
@ -251,10 +301,10 @@ public class MiniSolrCloudCluster {
* @return new Solr instance
*
*/
public JettySolrRunner startJettySolrRunner(String hostContext,
public JettySolrRunner startJettySolrRunner(String name, String hostContext,
SortedMap<ServletHolder, String> extraServlets,
SortedMap<Class<? extends Filter>, String> extraRequestFilters) throws Exception {
return startJettySolrRunner(hostContext, extraServlets, extraRequestFilters, null);
return startJettySolrRunner(name, hostContext, extraServlets, extraRequestFilters, null);
}
/**
@ -267,42 +317,30 @@ public class MiniSolrCloudCluster {
*
* @return new Solr instance
*/
public JettySolrRunner startJettySolrRunner(String hostContext,
public JettySolrRunner startJettySolrRunner(String name, String hostContext,
SortedMap<ServletHolder, String> extraServlets,
SortedMap<Class<? extends Filter>, String> extraRequestFilters, SSLConfig sslConfig) throws Exception {
return startJettySolrRunner(hostContext, JettyConfig.builder()
return startJettySolrRunner(name, hostContext, JettyConfig.builder()
.withServlets(extraServlets)
.withFilters(extraRequestFilters)
.withSSLConfig(sslConfig)
.build());
}
/**
* Start a new Solr instance
*
* @param config a JettyConfig for the instance's {@link org.apache.solr.client.solrj.embedded.JettySolrRunner}
*
* @return a JettySolrRunner
*/
public JettySolrRunner startJettySolrRunner(JettyConfig config) throws Exception {
return startJettySolrRunner(config.context, config);
}
/**
* Start a new Solr instance on a particular servlet context
*
* @param name the instance name
* @param hostContext the context to run on
* @param config a JettyConfig for the instance's {@link org.apache.solr.client.solrj.embedded.JettySolrRunner}
*
* @return a JettySolrRunner
*/
public JettySolrRunner startJettySolrRunner(String hostContext, JettyConfig config) throws Exception {
return startJettySolrRunner(null, hostContext, config);
}
public JettySolrRunner startJettySolrRunner(Integer testDirsIdx, String hostContext, JettyConfig config) throws Exception {
public JettySolrRunner startJettySolrRunner(String name, String hostContext, JettyConfig config) throws Exception {
Path runnerPath = createInstancePath(name);
String context = getHostContextSuitableForServletContext(hostContext);
JettyConfig newConfig = JettyConfig.builder(config).setContext(context).build();
JettySolrRunner jetty = new JettySolrRunner((testDirsIdx != null ? testDirs[testDirsIdx.intValue()] : testDir).getAbsolutePath(), newConfig);
JettySolrRunner jetty = new JettySolrRunner(runnerPath.toString(), newConfig);
jetty.start();
jettys.add(jetty);
return jetty;
@ -314,7 +352,7 @@ public class MiniSolrCloudCluster {
* @return a JettySolrRunner
*/
public JettySolrRunner startJettySolrRunner() throws Exception {
return startJettySolrRunner(jettyConfig);
return startJettySolrRunner(newNodeName(), jettyConfig.context, jettyConfig);
}
/**
@ -331,6 +369,7 @@ public class MiniSolrCloudCluster {
protected JettySolrRunner startJettySolrRunner(JettySolrRunner jetty) throws Exception {
jetty.start();
jettys.add(jetty);
return jetty;
}