/* * 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.handler.admin; import com.carrotsearch.randomizedtesting.rules.SystemPropertiesRestoreRule; import org.apache.commons.codec.Charsets; import org.apache.commons.io.FileUtils; import org.apache.solr.SolrTestCaseJ4; import org.apache.solr.client.solrj.embedded.JettySolrRunner; import org.apache.solr.client.solrj.impl.HttpSolrServer; import org.apache.solr.client.solrj.request.CoreAdminRequest; import org.apache.solr.common.SolrException; import org.apache.solr.common.SolrInputDocument; import org.apache.solr.common.params.CoreAdminParams; import org.apache.solr.common.util.NamedList; import org.apache.solr.core.CoreContainer; import org.apache.solr.core.CoreDescriptor; import org.apache.solr.core.SolrCore; import org.apache.solr.core.SolrXMLCoresLocator; import org.apache.solr.response.SolrQueryResponse; import org.junit.BeforeClass; import org.junit.Rule; import org.junit.Test; import org.junit.rules.RuleChain; import org.junit.rules.TestRule; import java.io.File; import java.util.Map; public class CoreAdminHandlerTest extends SolrTestCaseJ4 { @BeforeClass public static void beforeClass() throws Exception { initCore("solrconfig.xml", "schema.xml"); } @Rule public TestRule solrTestRules = RuleChain.outerRule(new SystemPropertiesRestoreRule()); public String getCoreName() { return this.getClass().getName() + "_sys_vars"; } @Test public void testCreateWithSysVars() throws Exception { useFactory(null); // I require FS-based indexes for this test. final File workDir = new File(TEMP_DIR, getCoreName()); if (workDir.exists()) { FileUtils.deleteDirectory(workDir); } assertTrue("Failed to mkdirs workDir", workDir.mkdirs()); String coreName = "with_sys_vars"; File instDir = new File(workDir, coreName); File subHome = new File(instDir, "conf"); assertTrue("Failed to make subdirectory ", subHome.mkdirs()); // Be sure we pick up sysvars when we create this String srcDir = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf"; FileUtils.copyFile(new File(srcDir, "schema-tiny.xml"), new File(subHome, "schema_ren.xml")); FileUtils.copyFile(new File(srcDir, "solrconfig-minimal.xml"), new File(subHome, "solrconfig_ren.xml")); FileUtils.copyFile(new File(srcDir, "solrconfig.snippet.randomindexconfig.xml"), new File(subHome, "solrconfig.snippet.randomindexconfig.xml")); final CoreContainer cores = h.getCoreContainer(); SolrXMLCoresLocator.NonPersistingLocator locator = (SolrXMLCoresLocator.NonPersistingLocator) cores.getCoresLocator(); final CoreAdminHandler admin = new CoreAdminHandler(cores); // create a new core (using CoreAdminHandler) w/ properties System.setProperty("INSTDIR_TEST", instDir.getAbsolutePath()); System.setProperty("CONFIG_TEST", "solrconfig_ren.xml"); System.setProperty("SCHEMA_TEST", "schema_ren.xml"); File dataDir = new File(workDir.getAbsolutePath(), "data_diff"); System.setProperty("DATA_TEST", dataDir.getAbsolutePath()); SolrQueryResponse resp = new SolrQueryResponse(); admin.handleRequestBody (req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.NAME, getCoreName(), CoreAdminParams.INSTANCE_DIR, "${INSTDIR_TEST}", CoreAdminParams.CONFIG, "${CONFIG_TEST}", CoreAdminParams.SCHEMA, "${SCHEMA_TEST}", CoreAdminParams.DATA_DIR, "${DATA_TEST}"), resp); assertNull("Exception on create", resp.getException()); // First assert that these values are persisted. h.validateXPath (locator.xml ,"/solr/cores/core[@name='" + getCoreName() + "' and @instanceDir='${INSTDIR_TEST}']" ,"/solr/cores/core[@name='" + getCoreName() + "' and @dataDir='${DATA_TEST}']" ,"/solr/cores/core[@name='" + getCoreName() + "' and @schema='${SCHEMA_TEST}']" ,"/solr/cores/core[@name='" + getCoreName() + "' and @config='${CONFIG_TEST}']" ); // Now assert that certain values are properly dereferenced in the process of creating the core, see // SOLR-4982. // Should NOT be a datadir named ${DATA_TEST} (literal). This is the bug after all File badDir = new File(instDir, "${DATA_TEST}"); assertFalse("Should have substituted the sys var, found file " + badDir.getAbsolutePath(), badDir.exists()); // For the other 3 vars, we couldn't get past creating the core fi dereferencing didn't work correctly. // Should have segments in the directory pointed to by the ${DATA_TEST}. File test = new File(dataDir, "index"); assertTrue("Should have found index dir at " + test.getAbsolutePath(), test.exists()); test = new File(test,"segments.gen"); assertTrue("Should have found segments.gen at " + test.getAbsolutePath(), test.exists()); // Cleanup FileUtils.deleteDirectory(workDir); } @Test public void testCoreAdminHandler() throws Exception { final File workDir = new File(TEMP_DIR, this.getClass().getName()); if (workDir.exists()) { FileUtils.deleteDirectory(workDir); } assertTrue("Failed to mkdirs workDir", workDir.mkdirs()); final CoreContainer cores = h.getCoreContainer(); final CoreAdminHandler admin = new CoreAdminHandler(cores); String instDir = null; { SolrCore template = null; try { template = cores.getCore("collection1"); instDir = template.getCoreDescriptor().getInstanceDir(); } finally { if (null != template) template.close(); } } final File instDirFile = new File(instDir); assertTrue("instDir doesn't exist: " + instDir, instDirFile.exists()); final File instPropFile = new File(workDir, "instProp"); FileUtils.copyDirectory(instDirFile, instPropFile); // create a new core (using CoreAdminHandler) w/ properties SolrQueryResponse resp = new SolrQueryResponse(); admin.handleRequestBody (req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.INSTANCE_DIR, instPropFile.getAbsolutePath(), CoreAdminParams.NAME, "props", CoreAdminParams.PROPERTY_PREFIX + "hoss","man", CoreAdminParams.PROPERTY_PREFIX + "foo","baz"), resp); assertNull("Exception on create", resp.getException()); CoreDescriptor cd = cores.getCoreDescriptor("props"); assertNotNull("Core not added!", cd); assertEquals(cd.getCoreProperty("hoss", null), "man"); assertEquals(cd.getCoreProperty("foo", null), "baz"); // attempt to create a bogus core and confirm failure ignoreException("Could not load config"); try { resp = new SolrQueryResponse(); admin.handleRequestBody (req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.NAME, "bogus_dir_core", CoreAdminParams.INSTANCE_DIR, "dir_does_not_exist_127896"), resp); fail("bogus collection created ok"); } catch (SolrException e) { // :NOOP: // :TODO: CoreAdminHandler's exception messages are terrible, otherwise we could assert something useful here } unIgnoreException("Could not load config"); // check specifically for status of the failed core name resp = new SolrQueryResponse(); admin.handleRequestBody (req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.STATUS.toString(), CoreAdminParams.CORE, "bogus_dir_core"), resp); Map<String,Exception> failures = (Map<String,Exception>) resp.getValues().get("initFailures"); assertNotNull("core failures is null", failures); NamedList<Object> status = (NamedList<Object>)resp.getValues().get("status"); assertNotNull("core status is null", status); assertEquals("wrong number of core failures", 1, failures.size()); Exception fail = failures.get("bogus_dir_core"); assertNotNull("null failure for test core", fail); assertTrue("init failure doesn't mention problem: " + fail.getCause().getMessage(), 0 < fail.getCause().getMessage().indexOf("dir_does_not_exist")); assertEquals("bogus_dir_core status isn't empty", 0, ((NamedList)status.get("bogus_dir_core")).size()); // :TODO: because of SOLR-3665 we can't ask for status from all cores // cleanup FileUtils.deleteDirectory(workDir); } @Test public void testDeleteInstanceDir() throws Exception { File solrHomeDirectory = new File(TEMP_DIR, getClass().getName() + "-corex-" + System.currentTimeMillis()); solrHomeDirectory.mkdirs(); copySolrHomeToTemp(solrHomeDirectory, "corex", true); File corex = new File(solrHomeDirectory, "corex"); FileUtils.write(new File(corex, "core.properties"), "", Charsets.UTF_8.toString()); JettySolrRunner runner = new JettySolrRunner(solrHomeDirectory.getAbsolutePath(), "/solr", 0); HttpSolrServer server = null; try { runner.start(); server = new HttpSolrServer("http://localhost:" + runner.getLocalPort() + "/solr/corex"); server.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); server.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); SolrInputDocument doc = new SolrInputDocument(); doc.addField("id", "123"); server.add(doc); server.commit(); server.shutdown(); server = new HttpSolrServer("http://localhost:" + runner.getLocalPort() + "/solr"); server.setConnectionTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); server.setSoTimeout(SolrTestCaseJ4.DEFAULT_CONNECTION_TIMEOUT); CoreAdminRequest.Unload req = new CoreAdminRequest.Unload(false); req.setDeleteInstanceDir(true); req.setCoreName("corex"); req.process(server); server.shutdown(); runner.stop(); assertFalse("Instance directory exists after core unload with deleteInstanceDir=true : " + corex, corex.exists()); } catch (Exception e) { log.error("Exception testing core unload with deleteInstanceDir=true", e); } finally { if (server != null) { server.shutdown(); } if (!runner.isStopped()) { runner.stop(); } recurseDelete(solrHomeDirectory); } } @Test public void testNonexistentCoreReload() throws Exception { final CoreAdminHandler admin = new CoreAdminHandler(h.getCoreContainer()); SolrQueryResponse resp = new SolrQueryResponse(); try { admin.handleRequestBody( req(CoreAdminParams.ACTION, CoreAdminParams.CoreAdminAction.RELOAD.toString(), CoreAdminParams.CORE, "non-existent-core") , resp); fail("Was able to successfully reload non-existent-core"); } catch (Exception e) { assertEquals("Expected error message for non-existent core.", "Core with core name [non-existent-core] does not exist.", e.getMessage()); } } }