blob: 02530a199199b21815438d41efb0badb2153fc90 [file] [log] [blame]
package org.apache.solr.cloud;
/*
* 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.
*/
import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.apache.lucene.util.LuceneTestCase.Slow;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.common.cloud.ClusterState;
import org.apache.solr.common.cloud.Replica;
import org.apache.solr.common.cloud.Slice;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkNodeProps;
import org.apache.solr.common.cloud.ZkStateReader;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreContainer.Initializer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.zookeeper.CreateMode;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Slow
public class ClusterStateUpdateTest extends SolrTestCaseJ4 {
protected static Logger log = LoggerFactory
.getLogger(AbstractZkTestCase.class);
private static final boolean VERBOSE = false;
protected ZkTestServer zkServer;
protected String zkDir;
private CoreContainer container1;
private CoreContainer container2;
private CoreContainer container3;
private File dataDir1;
private File dataDir2;
private File dataDir3;
private File dataDir4;
private Initializer init2;
@BeforeClass
public static void beforeClass() {
System.setProperty("solrcloud.skip.autorecovery", "true");
}
@AfterClass
public static void afterClass() throws InterruptedException {
System.clearProperty("solrcloud.skip.autorecovery");
}
@Override
public void setUp() throws Exception {
super.setUp();
createTempDir();
System.setProperty("zkClientTimeout", "3000");
zkDir = dataDir.getAbsolutePath() + File.separator
+ "zookeeper/server1/data";
zkServer = new ZkTestServer(zkDir);
zkServer.run();
System.setProperty("zkHost", zkServer.getZkAddress());
AbstractZkTestCase.buildZooKeeper(zkServer.getZkHost(), zkServer
.getZkAddress(), "solrconfig.xml", "schema.xml");
log.info("####SETUP_START " + getTestName());
dataDir1 = new File(dataDir + File.separator + "data1");
dataDir1.mkdirs();
dataDir2 = new File(dataDir + File.separator + "data2");
dataDir2.mkdirs();
dataDir3 = new File(dataDir + File.separator + "data3");
dataDir3.mkdirs();
dataDir4 = new File(dataDir + File.separator + "data4");
dataDir4.mkdirs();
// set some system properties for use by tests
System.setProperty("solr.test.sys.prop1", "propone");
System.setProperty("solr.test.sys.prop2", "proptwo");
System.setProperty("solr.solr.home", TEST_HOME());
System.setProperty("hostPort", "1661");
CoreContainer.Initializer init1 = new CoreContainer.Initializer();
System.setProperty("solr.data.dir", ClusterStateUpdateTest.this.dataDir1.getAbsolutePath());
container1 = init1.initialize();
System.clearProperty("hostPort");
System.setProperty("hostPort", "1662");
init2 = new CoreContainer.Initializer();
System.setProperty("solr.data.dir", ClusterStateUpdateTest.this.dataDir2.getAbsolutePath());
container2 = init2.initialize();
System.clearProperty("hostPort");
System.setProperty("hostPort", "1663");
CoreContainer.Initializer init3 = new CoreContainer.Initializer();
System.setProperty("solr.data.dir", ClusterStateUpdateTest.this.dataDir3.getAbsolutePath());
container3 = init3.initialize();
System.clearProperty("hostPort");
System.clearProperty("solr.solr.home");
log.info("####SETUP_END " + getTestName());
}
@Test
public void testCoreRegistration() throws Exception {
System.setProperty("solrcloud.update.delay", "1");
Map<String,Object> props2 = new HashMap<String,Object>();
props2.put("configName", "conf1");
ZkNodeProps zkProps2 = new ZkNodeProps(props2);
SolrZkClient zkClient = new SolrZkClient(zkServer.getZkAddress(),
AbstractZkTestCase.TIMEOUT);
zkClient.makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/testcore",
ZkStateReader.toJSON(zkProps2), CreateMode.PERSISTENT, true);
zkClient.makePath(ZkStateReader.COLLECTIONS_ZKNODE + "/testcore/shards",
CreateMode.PERSISTENT, true);
zkClient.close();
CoreDescriptor dcore = new CoreDescriptor(container1, "testcore",
"testcore");
dcore.setDataDir(dataDir4.getAbsolutePath());
SolrCore core = container1.create(dcore);
container1.register(core, false);
ZkController zkController2 = container2.getZkController();
String host = zkController2.getHostName();
// slight pause - TODO: takes an oddly long amount of time to schedule tasks
// with almost no delay ...
ClusterState clusterState2 = null;
Map<String,Slice> slices = null;
for (int i = 75; i > 0; i--) {
clusterState2 = zkController2.getClusterState();
slices = clusterState2.getSlicesMap("testcore");
if (slices != null && slices.containsKey("shard1")
&& slices.get("shard1").getReplicasMap().size() > 0) {
break;
}
Thread.sleep(500);
}
assertNotNull(slices);
assertTrue(slices.containsKey("shard1"));
Slice slice = slices.get("shard1");
assertEquals("shard1", slice.getName());
Map<String,Replica> shards = slice.getReplicasMap();
assertEquals(1, shards.size());
Replica zkProps = shards.get(host + ":1661_solr_testcore");
assertNotNull(zkProps);
assertEquals(host + ":1661_solr", zkProps.getStr(ZkStateReader.NODE_NAME_PROP));
assertEquals("http://" + host + ":1661/solr", zkProps.getStr(ZkStateReader.BASE_URL_PROP));
Set<String> liveNodes = clusterState2.getLiveNodes();
assertNotNull(liveNodes);
assertEquals(3, liveNodes.size());
container3.shutdown();
// slight pause (15s timeout) for watch to trigger
for(int i = 0; i < (5 * 15); i++) {
if(zkController2.getClusterState().getLiveNodes().size() == 2) {
break;
}
Thread.sleep(200);
}
assertEquals(2, zkController2.getClusterState().getLiveNodes().size());
// quickly kill / start client
container2.getZkController().getZkClient().getSolrZooKeeper().getConnection()
.disconnect();
container2.shutdown();
container2 = init2.initialize();
// pause for watch to trigger
for(int i = 0; i < 200; i++) {
if (container1.getZkController().getClusterState().liveNodesContain(
container2.getZkController().getNodeName())) {
break;
}
Thread.sleep(100);
}
assertTrue(container1.getZkController().getClusterState().liveNodesContain(
container2.getZkController().getNodeName()));
// core.close(); // don't close - this core is managed by container1 now
}
@Override
public void tearDown() throws Exception {
if (VERBOSE) {
printLayout(zkServer.getZkHost());
}
container1.shutdown();
container2.shutdown();
container3.shutdown();
zkServer.shutdown();
super.tearDown();
System.clearProperty("zkClientTimeout");
System.clearProperty("zkHost");
System.clearProperty("hostPort");
System.clearProperty("solrcloud.update.delay");
}
static void printLayout(String zkHost) throws Exception {
SolrZkClient zkClient = new SolrZkClient(
zkHost, AbstractZkTestCase.TIMEOUT);
zkClient.printLayoutToStdOut();
zkClient.close();
}
}