private void testNodesUsedByCreate() throws Exception { // we can use this client because we just want base url final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0)); ModifiableSolrParams params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); params.set("numShards", 2); params.set(REPLICATION_FACTOR, 2); String collectionName = "nodes_used_collection"; params.set("name", collectionName); if (secondConfigSet) { params.set("collection.configName", "conf1"); } QueryRequest request = new QueryRequest(params); request.setPath("/admin/collections"); createNewSolrServer("", baseUrl).request(request); List<Integer> numShardsNumReplicaList = new ArrayList<Integer>(); numShardsNumReplicaList.add(2); numShardsNumReplicaList.add(2); checkForCollection("nodes_used_collection", numShardsNumReplicaList, null); List<String> createNodeList = new ArrayList<String>(); Set<String> liveNodes = cloudClient.getZkStateReader().getClusterState().getLiveNodes(); for (String node : liveNodes) { createNodeList.add(node); } DocCollection col = cloudClient.getZkStateReader().getClusterState().getCollection("nodes_used_collection"); Collection<Slice> slices = col.getSlices(); for (Slice slice : slices) { Collection<Replica> replicas = slice.getReplicas(); for (Replica replica : replicas) { createNodeList.remove(replica.getNodeName()); } } assertEquals(createNodeList.toString(), 1, createNodeList.size()); }
private void deletePartiallyCreatedCollection() throws Exception { final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0)); String collectionName = "halfdeletedcollection"; Create createCmd = new Create(); createCmd.setCoreName("halfdeletedcollection_shard1_replica1"); createCmd.setCollection(collectionName); String dataDir = SolrTestCaseJ4.dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "halfcollection" + "_hdn"; createCmd.setDataDir(dataDir); createCmd.setNumShards(2); if (secondConfigSet) { createCmd.setCollectionConfigName("conf1"); } createNewSolrServer("", baseUrl).request(createCmd); ModifiableSolrParams params = new ModifiableSolrParams(); params.set("action", CollectionAction.DELETE.toString()); params.set("name", collectionName); QueryRequest request = new QueryRequest(params); request.setPath("/admin/collections"); NamedList<Object> resp = createNewSolrServer("", baseUrl).request(request); checkForMissingCollection(collectionName); // now creating that collection should work params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); params.set("name", collectionName); params.set("numShards", 2); request = new QueryRequest(params); request.setPath("/admin/collections"); if (secondConfigSet) { params.set("collection.configName", "conf1"); } resp = createNewSolrServer("", baseUrl).request(request); }
private void testCollectionsAPI() throws Exception { // TODO: fragile - because we dont pass collection.confName, it will only // find a default if a conf set with a name matching the collection name is found, or // if there is only one conf set. That and the fact that other tests run first in this // env make this pretty fragile // create new collections rapid fire Map<String, List<Integer>> collectionInfos = new HashMap<String, List<Integer>>(); int cnt = random().nextInt(TEST_NIGHTLY ? 6 : 3) + 1; for (int i = 0; i < cnt; i++) { int numShards = _TestUtil.nextInt(random(), 0, shardCount) + 1; int replicationFactor = _TestUtil.nextInt(random(), 0, 3) + 1; int maxShardsPerNode = (((numShards * replicationFactor) / getCommonCloudSolrServer() .getZkStateReader() .getClusterState() .getLiveNodes() .size())) + 1; CloudSolrServer client = null; try { if (i == 0) { // Test if we can create a collection through CloudSolrServer where // you havnt set default-collection // This is nice because you want to be able to create you first // collection using CloudSolrServer, and in such case there is // nothing reasonable to set as default-collection client = createCloudClient(null); } else if (i == 1) { // Test if we can create a collection through CloudSolrServer where // you have set default-collection to a non-existing collection // This is nice because you want to be able to create you first // collection using CloudSolrServer, and in such case there is // nothing reasonable to set as default-collection, but you might want // to use the same CloudSolrServer throughout the entire // lifetime of your client-application, so it is nice to be able to // set a default-collection on this CloudSolrServer once and for all // and use this CloudSolrServer to create the collection client = createCloudClient("awholynewcollection_" + i); } if (secondConfigSet) { createCollection( collectionInfos, "awholynewcollection_" + i, numShards, replicationFactor, maxShardsPerNode, client, null, "conf2"); } else { createCollection( collectionInfos, "awholynewcollection_" + i, numShards, replicationFactor, maxShardsPerNode, client, null); } } finally { if (client != null) client.shutdown(); } } Set<Entry<String, List<Integer>>> collectionInfosEntrySet = collectionInfos.entrySet(); for (Entry<String, List<Integer>> entry : collectionInfosEntrySet) { String collection = entry.getKey(); List<Integer> list = entry.getValue(); checkForCollection(collection, list, null); String url = getUrlFromZk(collection); HttpSolrServer collectionClient = new HttpSolrServer(url); // poll for a second - it can take a moment before we are ready to serve waitForNon403or404or503(collectionClient); } // sometimes we restart one of the jetty nodes if (random().nextBoolean()) { JettySolrRunner jetty = jettys.get(random().nextInt(jettys.size())); ChaosMonkey.stop(jetty); ChaosMonkey.start(jetty); for (Entry<String, List<Integer>> entry : collectionInfosEntrySet) { String collection = entry.getKey(); List<Integer> list = entry.getValue(); checkForCollection(collection, list, null); String url = getUrlFromZk(collection); HttpSolrServer collectionClient = new HttpSolrServer(url); // poll for a second - it can take a moment before we are ready to serve waitForNon403or404or503(collectionClient); } } // sometimes we restart zookeeper if (random().nextBoolean()) { zkServer.shutdown(); zkServer = new ZkTestServer(zkServer.getZkDir(), zkServer.getPort()); zkServer.run(); } // sometimes we cause a connection loss - sometimes it will hit the overseer if (random().nextBoolean()) { JettySolrRunner jetty = jettys.get(random().nextInt(jettys.size())); ChaosMonkey.causeConnectionLoss(jetty); } ZkStateReader zkStateReader = getCommonCloudSolrServer().getZkStateReader(); for (int j = 0; j < cnt; j++) { waitForRecoveriesToFinish("awholynewcollection_" + j, zkStateReader, false); if (secondConfigSet) { // let's see if they are using the second config set byte[] data = zkStateReader .getZkClient() .getData( ZkStateReader.COLLECTIONS_ZKNODE + "/" + "awholynewcollection_" + j, null, null, true); assertNotNull(data); ZkNodeProps props = ZkNodeProps.load(data); String configName = props.getStr(ZkController.CONFIGNAME_PROP); assertEquals("conf2", configName); } } checkInstanceDirs(jettys.get(0)); List<String> collectionNameList = new ArrayList<String>(); collectionNameList.addAll(collectionInfos.keySet()); String collectionName = collectionNameList.get(random().nextInt(collectionNameList.size())); String url = getUrlFromZk(collectionName); HttpSolrServer collectionClient = new HttpSolrServer(url); // lets try and use the solrj client to index a couple documents SolrInputDocument doc1 = getDoc(id, 6, i1, -600, tlong, 600, t1, "humpty dumpy sat on a wall"); SolrInputDocument doc2 = getDoc(id, 7, i1, -600, tlong, 600, t1, "humpty dumpy3 sat on a walls"); SolrInputDocument doc3 = getDoc(id, 8, i1, -600, tlong, 600, t1, "humpty dumpy2 sat on a walled"); collectionClient.add(doc1); collectionClient.add(doc2); collectionClient.add(doc3); collectionClient.commit(); assertEquals(3, collectionClient.query(new SolrQuery("*:*")).getResults().getNumFound()); // lets try a collection reload // get core open times Map<String, Long> urlToTimeBefore = new HashMap<String, Long>(); collectStartTimes(collectionName, urlToTimeBefore); assertTrue(urlToTimeBefore.size() > 0); ModifiableSolrParams params = new ModifiableSolrParams(); params.set("action", CollectionAction.RELOAD.toString()); params.set("name", collectionName); QueryRequest request = new QueryRequest(params); request.setPath("/admin/collections"); // we can use this client because we just want base url final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0)); createNewSolrServer("", baseUrl).request(request); // reloads make take a short while boolean allTimesAreCorrect = waitForReloads(collectionName, urlToTimeBefore); assertTrue("some core start times did not change on reload", allTimesAreCorrect); waitForRecoveriesToFinish("awholynewcollection_" + (cnt - 1), zkStateReader, false); // remove a collection params = new ModifiableSolrParams(); params.set("action", CollectionAction.DELETE.toString()); params.set("name", collectionName); request = new QueryRequest(params); request.setPath("/admin/collections"); createNewSolrServer("", baseUrl).request(request); // ensure its out of the state checkForMissingCollection(collectionName); // collectionNameList.remove(collectionName); // remove an unknown collection params = new ModifiableSolrParams(); params.set("action", CollectionAction.DELETE.toString()); params.set("name", "unknown_collection"); request = new QueryRequest(params); request.setPath("/admin/collections"); boolean exp = false; try { createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { exp = true; } assertTrue("Expected exception", exp); // create another collection should still work params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); params.set("numShards", 1); params.set(REPLICATION_FACTOR, 2); collectionName = "acollectionafterbaddelete"; params.set("name", collectionName); if (secondConfigSet) { params.set("collection.configName", "conf1"); } request = new QueryRequest(params); request.setPath("/admin/collections"); createNewSolrServer("", baseUrl).request(request); List<Integer> list = new ArrayList<Integer>(2); list.add(1); list.add(2); checkForCollection(collectionName, list, null); url = getUrlFromZk(collectionName); collectionClient = new HttpSolrServer(url); // poll for a second - it can take a moment before we are ready to serve waitForNon403or404or503(collectionClient); for (int j = 0; j < cnt; j++) { waitForRecoveriesToFinish(collectionName, zkStateReader, false); } // test maxShardsPerNode int numLiveNodes = getCommonCloudSolrServer().getZkStateReader().getClusterState().getLiveNodes().size(); int numShards = (numLiveNodes / 2) + 1; int replicationFactor = 2; int maxShardsPerNode = 1; collectionInfos = new HashMap<String, List<Integer>>(); CloudSolrServer client = createCloudClient("awholynewcollection_" + cnt); try { exp = false; try { createCollection( collectionInfos, "awholynewcollection_" + cnt, numShards, replicationFactor, maxShardsPerNode, client, null, "conf1"); } catch (SolrException e) { exp = true; } assertTrue("expected exception", exp); } finally { client.shutdown(); } // Test createNodeSet numLiveNodes = getCommonCloudSolrServer().getZkStateReader().getClusterState().getLiveNodes().size(); List<String> createNodeList = new ArrayList<String>(); int numOfCreateNodes = numLiveNodes / 2; assertFalse( "createNodeSet test is pointless with only " + numLiveNodes + " nodes running", numOfCreateNodes == 0); int i = 0; for (String liveNode : getCommonCloudSolrServer().getZkStateReader().getClusterState().getLiveNodes()) { if (i < numOfCreateNodes) { createNodeList.add(liveNode); i++; } else { break; } } maxShardsPerNode = 2; numShards = createNodeList.size() * maxShardsPerNode; replicationFactor = 1; collectionInfos = new HashMap<String, List<Integer>>(); client = createCloudClient("awholynewcollection_" + (cnt + 1)); try { createCollection( collectionInfos, "awholynewcollection_" + (cnt + 1), numShards, replicationFactor, maxShardsPerNode, client, StrUtils.join(createNodeList, ','), "conf1"); } finally { client.shutdown(); } checkForCollection( collectionInfos.keySet().iterator().next(), collectionInfos.entrySet().iterator().next().getValue(), createNodeList); checkNoTwoShardsUseTheSameIndexDir(); }
private void testErrorHandling() throws Exception { final String baseUrl = getBaseUrl((HttpSolrServer) clients.get(0)); // try a bad action ModifiableSolrParams params = new ModifiableSolrParams(); params.set("action", "BADACTION"); String collectionName = "badactioncollection"; params.set("name", collectionName); params.set("numShards", 2); QueryRequest request = new QueryRequest(params); request.setPath("/admin/collections"); boolean gotExp = false; NamedList<Object> resp = null; try { resp = createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { gotExp = true; } assertTrue(gotExp); // leave out required param name params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); params.set("numShards", 2); collectionName = "collection"; // No Name // params.set("name", collectionName); if (secondConfigSet) { params.set("collection.configName", "conf1"); } request = new QueryRequest(params); request.setPath("/admin/collections"); gotExp = false; resp = null; try { resp = createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { gotExp = true; } assertTrue(gotExp); // Too many replicas params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); collectionName = "collection"; params.set("name", collectionName); params.set("numShards", 2); if (secondConfigSet) { params.set("collection.configName", "conf1"); } params.set(REPLICATION_FACTOR, 10); request = new QueryRequest(params); request.setPath("/admin/collections"); gotExp = false; resp = null; try { resp = createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { gotExp = true; } assertTrue(gotExp); // No numShards should fail params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); collectionName = "acollection"; params.set("name", collectionName); params.set(REPLICATION_FACTOR, 10); if (secondConfigSet) { params.set("collection.configName", "conf1"); } request = new QueryRequest(params); request.setPath("/admin/collections"); gotExp = false; resp = null; try { resp = createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { gotExp = true; } assertTrue(gotExp); // 0 numShards should fail params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); collectionName = "acollection"; params.set("name", collectionName); params.set(REPLICATION_FACTOR, 10); params.set("numShards", 0); if (secondConfigSet) { params.set("collection.configName", "conf1"); } request = new QueryRequest(params); request.setPath("/admin/collections"); gotExp = false; resp = null; try { resp = createNewSolrServer("", baseUrl).request(request); } catch (SolrException e) { gotExp = true; } assertTrue(gotExp); // Fail on one node // first we make a core with the core name the collections api // will try and use - this will cause our mock fail Create createCmd = new Create(); createCmd.setCoreName("halfcollection_shard1_replica1"); createCmd.setCollection("halfcollectionblocker"); String dataDir = SolrTestCaseJ4.dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "halfcollection" + "_3n"; createCmd.setDataDir(dataDir); createCmd.setNumShards(1); if (secondConfigSet) { createCmd.setCollectionConfigName("conf1"); } createNewSolrServer("", baseUrl).request(createCmd); createCmd = new Create(); createCmd.setCoreName("halfcollection_shard1_replica1"); createCmd.setCollection("halfcollectionblocker2"); dataDir = SolrTestCaseJ4.dataDir.getAbsolutePath() + File.separator + System.currentTimeMillis() + "halfcollection" + "_3n"; createCmd.setDataDir(dataDir); createCmd.setNumShards(1); if (secondConfigSet) { createCmd.setCollectionConfigName("conf1"); } createNewSolrServer("", getBaseUrl((HttpSolrServer) clients.get(1))).request(createCmd); params = new ModifiableSolrParams(); params.set("action", CollectionAction.CREATE.toString()); collectionName = "halfcollection"; params.set("name", collectionName); params.set("numShards", 2); params.set("wt", "xml"); if (secondConfigSet) { params.set("collection.configName", "conf1"); } String nn1 = ((SolrDispatchFilter) jettys.get(0).getDispatchFilter().getFilter()) .getCores() .getZkController() .getNodeName(); String nn2 = ((SolrDispatchFilter) jettys.get(1).getDispatchFilter().getFilter()) .getCores() .getZkController() .getNodeName(); params.set(OverseerCollectionProcessor.CREATE_NODE_SET, nn1 + "," + nn2); request = new QueryRequest(params); request.setPath("/admin/collections"); gotExp = false; resp = createNewSolrServer("", baseUrl).request(request); SimpleOrderedMap success = (SimpleOrderedMap) resp.get("success"); SimpleOrderedMap failure = (SimpleOrderedMap) resp.get("failure"); assertNotNull(resp.toString(), success); assertNotNull(resp.toString(), failure); String val1 = success.getVal(0).toString(); String val2 = failure.getVal(0).toString(); assertTrue(val1.contains("SolrException") || val2.contains("SolrException")); }