SOLR-8308: Core gets inaccessible after RENAME operation with special characters

This commit is contained in:
Erick Erickson 2016-02-02 11:23:48 -08:00
parent 70ad8316f4
commit 70f87420ab
3 changed files with 96 additions and 28 deletions

View File

@ -144,6 +144,9 @@ New Features
* SOLR-8285: Ensure the /export handler works with NULL field values (Joel Bernstein) * SOLR-8285: Ensure the /export handler works with NULL field values (Joel Bernstein)
* SOLR-8308: Core gets inaccessible after RENAME operation with special characters
(Erik Hatcher, Erick Erickson)
Bug Fixes Bug Fixes
---------------------- ----------------------
* SOLR-8386: Add field option in the new admin UI schema page loads up even when no schemaFactory has been * SOLR-8386: Add field option in the new admin UI schema page loads up even when no schemaFactory has been
@ -590,6 +593,8 @@ Other Changes
* SOLR-8600: add & use ReRankQParserPlugin parameter [default] constants, * SOLR-8600: add & use ReRankQParserPlugin parameter [default] constants,
changed ReRankQuery.toString to use StringBuilder. (Christine Poerschke) changed ReRankQuery.toString to use StringBuilder. (Christine Poerschke)
* SOLR-8308: Core gets inaccessible after RENAME operation with special characters.
================== 5.4.1 ================== ================== 5.4.1 ==================
Bug Fixes Bug Fixes

View File

@ -32,6 +32,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future; import java.util.concurrent.Future;
import java.util.regex.Pattern;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@ -656,16 +657,25 @@ public class CoreContainer {
return coresLocator; return coresLocator;
} }
// Insure that the core name won't cause problems later on.
final static Pattern corePattern = Pattern.compile("^[\\._A-Za-z0-9]*$");
public void validateCoreName(String name) {
if (name == null || !corePattern.matcher(name).matches()) {
throw new IllegalArgumentException("Invalid core name: '" + name +
"' Names must consist entirely of periods, underscores and alphanumerics");
}
}
protected SolrCore registerCore(String name, SolrCore core, boolean registerInZk) { protected SolrCore registerCore(String name, SolrCore core, boolean registerInZk) {
if( core == null ) { if( core == null ) {
throw new RuntimeException( "Can not register a null core." ); throw new RuntimeException( "Can not register a null core." );
} }
if( name == null ||
name.indexOf( '/' ) >= 0 || // We can register a core when creating them via the admin UI, so we need to ensure that the dynamic descriptors
name.indexOf( '\\' ) >= 0 ){
throw new RuntimeException( "Invalid core name: "+name );
}
// We can register a core when creating them via the admin UI, so we need to insure that the dynamic descriptors
// are up to date // are up to date
CoreDescriptor cd = core.getCoreDescriptor(); CoreDescriptor cd = core.getCoreDescriptor();
if ((cd.isTransient() || ! cd.isLoadOnStartup()) if ((cd.isTransient() || ! cd.isLoadOnStartup())
@ -808,6 +818,7 @@ public class CoreContainer {
SolrCore core = null; SolrCore core = null;
try { try {
MDCLoggingContext.setCore(core); MDCLoggingContext.setCore(core);
validateCoreName(dcore.getName());
if (zkSys.getZkController() != null) { if (zkSys.getZkController() != null) {
zkSys.getZkController().preRegister(dcore); zkSys.getZkController().preRegister(dcore);
} }
@ -1010,6 +1021,7 @@ public class CoreContainer {
} }
public void rename(String name, String toName) { public void rename(String name, String toName) {
validateCoreName(toName);
try (SolrCore core = getCore(name)) { try (SolrCore core = getCore(name)) {
if (core != null) { if (core != null) {
registerCore(toName, core, true); registerCore(toName, core, true);

View File

@ -129,9 +129,24 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
final File instPropFile = new File(workDir, "instProp"); final File instPropFile = new File(workDir, "instProp");
FileUtils.copyDirectory(instDir.toFile(), instPropFile); FileUtils.copyDirectory(instDir.toFile(), instPropFile);
SolrQueryResponse resp = new SolrQueryResponse();
// Sneaking in a test for using a bad core name
try {
admin.handleRequestBody
(req(CoreAdminParams.ACTION,
CoreAdminParams.CoreAdminAction.CREATE.toString(),
CoreAdminParams.INSTANCE_DIR, instPropFile.getAbsolutePath(),
CoreAdminParams.NAME, "ugly$core=name"),
resp);
} catch (SolrException se) {
assertTrue("Expected error message for bad core name.", se.toString().contains("Invalid core name"));
}
CoreDescriptor cd = cores.getCoreDescriptor("ugly$core=name");
assertNull("Should NOT have added this core!", cd);
// create a new core (using CoreAdminHandler) w/ properties // create a new core (using CoreAdminHandler) w/ properties
SolrQueryResponse resp = new SolrQueryResponse();
admin.handleRequestBody admin.handleRequestBody
(req(CoreAdminParams.ACTION, (req(CoreAdminParams.ACTION,
CoreAdminParams.CoreAdminAction.CREATE.toString(), CoreAdminParams.CoreAdminAction.CREATE.toString(),
@ -142,7 +157,7 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
resp); resp);
assertNull("Exception on create", resp.getException()); assertNull("Exception on create", resp.getException());
CoreDescriptor cd = cores.getCoreDescriptor("props"); cd = cores.getCoreDescriptor("props");
assertNotNull("Core not added!", cd); assertNotNull("Core not added!", cd);
assertEquals(cd.getCoreProperty("hoss", null), "man"); assertEquals(cd.getCoreProperty("hoss", null), "man");
assertEquals(cd.getCoreProperty("foo", null), "baz"); assertEquals(cd.getCoreProperty("foo", null), "baz");
@ -189,6 +204,42 @@ public class CoreAdminHandlerTest extends SolrTestCaseJ4 {
0, ((NamedList)status.get("bogus_dir_core")).size()); 0, ((NamedList)status.get("bogus_dir_core")).size());
//Try renaming the core, we should fail
// First assert that the props core exists
cd = cores.getCoreDescriptor("props");
assertNotNull("Core disappeared!", cd);
// now rename it something else just for kicks since we don't actually test this that I could find.
admin.handleRequestBody
(req(CoreAdminParams.ACTION,
CoreAdminParams.CoreAdminAction.RENAME.toString(),
CoreAdminParams.CORE, "props",
CoreAdminParams.OTHER, "rename_me"),
resp);
cd = cores.getCoreDescriptor("rename_me");
assertNotNull("Core should have been renamed!", cd);
// Rename it something bogus and see if you get an exception, the old core is still there and the bogus one isn't
try {
admin.handleRequestBody
(req(CoreAdminParams.ACTION,
CoreAdminParams.CoreAdminAction.RENAME.toString(),
CoreAdminParams.CORE, "rename_me",
CoreAdminParams.OTHER, "bad$name"),
resp);
} catch (IllegalArgumentException iae) { // why the heck does create return a SolrException (admittedly wrapping an IAE)
assertTrue("Expected error message for bad core name.", iae.getMessage().contains("Invalid core name"));
}
cd = cores.getCoreDescriptor("bad$name");
assertNull("Core should NOT exist!", cd);
cd = cores.getCoreDescriptor("rename_me");
assertNotNull("Core should have been renamed!", cd);
// :TODO: because of SOLR-3665 we can't ask for status from all cores // :TODO: because of SOLR-3665 we can't ask for status from all cores
} }