mirror of https://github.com/apache/lucene.git
SOLR-5455: add managed schema name to the files the admin UI cannot edit
git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1542859 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
194238944c
commit
6e78f9a497
|
@ -36,6 +36,8 @@ import org.apache.solr.handler.RequestHandlerBase;
|
|||
import org.apache.solr.request.SolrQueryRequest;
|
||||
import org.apache.solr.response.RawResponseWriter;
|
||||
import org.apache.solr.response.SolrQueryResponse;
|
||||
import org.apache.solr.schema.IndexSchema;
|
||||
import org.apache.solr.schema.ManagedIndexSchema;
|
||||
import org.apache.zookeeper.KeeperException;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -170,13 +172,11 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
if (fname == null) {
|
||||
rsp.setException(new SolrException(ErrorCode.BAD_REQUEST, "No file name specified for write operation."));
|
||||
} else {
|
||||
if (coreContainer.isZooKeeperAware()) {
|
||||
if (isHiddenFile(rsp, fname) == false) {
|
||||
fname = fname.replace('\\', '/');
|
||||
if (isHiddenFile(req, rsp, fname, true) == false) {
|
||||
if (coreContainer.isZooKeeperAware()) {
|
||||
writeToZooKeeper(req, rsp, coreContainer);
|
||||
}
|
||||
} else {
|
||||
fname = fname.replace('\\', '/'); // normalize slashes. Should be done above too?
|
||||
if (isHiddenFile(rsp, fname) == false) {
|
||||
} else {
|
||||
writeToFileSystem(req, rsp);
|
||||
}
|
||||
}
|
||||
|
@ -186,21 +186,38 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
|
||||
// See if we should deal with this file
|
||||
|
||||
private boolean isHiddenFile(SolrQueryResponse rsp, String fnameIn) {
|
||||
private boolean isHiddenFile(SolrQueryRequest req, SolrQueryResponse rsp, String fnameIn, boolean reportError) {
|
||||
String fname = fnameIn.toUpperCase(Locale.ROOT);
|
||||
if (hiddenFiles.contains(fname) || hiddenFiles.contains("*")) {
|
||||
log.error("Cannot access " + fname);
|
||||
rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Can not access: " + fnameIn));
|
||||
if (reportError) {
|
||||
log.error("Cannot access " + fname);
|
||||
rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Can not access: " + fnameIn));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is slightly off, a valid path is something like ./schema.xml. I don't think it's worth the effort though
|
||||
// to fix it to handle all possibilities though.
|
||||
if (fname.indexOf("..") >= 0 || fname.startsWith(".")) {
|
||||
log.error("Invalid path: " + fname);
|
||||
rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn));
|
||||
if (reportError) {
|
||||
log.error("Invalid path: " + fname);
|
||||
rsp.setException(new SolrException(ErrorCode.FORBIDDEN, "Invalid path: " + fnameIn));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Make sure that if the schema is managed, we don't allow editing. Don't really want to put
|
||||
// this in the init since we're not entirely sure when the managed schema will get initialized relative to this
|
||||
// handler.
|
||||
SolrCore core = req.getCore();
|
||||
IndexSchema schema = core.getLatestSchema();
|
||||
if (schema instanceof ManagedIndexSchema) {
|
||||
String managed = schema.getResourceName();
|
||||
|
||||
if (fname.equalsIgnoreCase(managed)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -223,7 +240,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
adminFile = confPath;
|
||||
} else {
|
||||
fname = fname.replace('\\', '/'); // normalize slashes
|
||||
if (isHiddenFile(rsp, fname)) {
|
||||
if (isHiddenFile(req, rsp, fname, true)) {
|
||||
return null;
|
||||
}
|
||||
if (fname.startsWith("/")) { // Only files relative to conf are valid
|
||||
|
@ -291,7 +308,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
|
||||
NamedList<SimpleOrderedMap<Object>> files = new SimpleOrderedMap<SimpleOrderedMap<Object>>();
|
||||
for (String f : children) {
|
||||
if (isHiddenFile(rsp, f)) {
|
||||
if (isHiddenFile(req, rsp, f, false)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -452,13 +469,11 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
for( File f : adminFile.listFiles() ) {
|
||||
String path = f.getAbsolutePath().substring( basePath );
|
||||
path = path.replace( '\\', '/' ); // normalize slashes
|
||||
if( hiddenFiles.contains( path.toUpperCase(Locale.ROOT) ) ) {
|
||||
continue; // don't show 'hidden' files
|
||||
|
||||
if (isHiddenFile(req, rsp, f.getName().replace('\\', '/'), false)) {
|
||||
continue;
|
||||
}
|
||||
if( f.isHidden() || f.getName().startsWith( "." ) ) {
|
||||
continue; // skip hidden system files...
|
||||
}
|
||||
|
||||
|
||||
SimpleOrderedMap<Object> fileInfo = new SimpleOrderedMap<Object>();
|
||||
files.add( path, fileInfo );
|
||||
if( f.isDirectory() ) {
|
||||
|
@ -480,7 +495,7 @@ public class ShowFileRequestHandler extends RequestHandlerBase
|
|||
req.setParams(params);
|
||||
|
||||
ContentStreamBase content = new ContentStreamBase.FileStream( adminFile );
|
||||
content.setContentType( req.getParams().get( USE_CONTENT_TYPE ) );
|
||||
content.setContentType(req.getParams().get(USE_CONTENT_TYPE));
|
||||
|
||||
rsp.add(RawResponseWriter.CONTENT, content);
|
||||
}
|
||||
|
|
|
@ -16,23 +16,20 @@ package org.apache.solr.schema;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.apache.solr.client.solrj.ResponseParser;
|
||||
import org.apache.solr.client.solrj.SolrServer;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.impl.HttpSolrServer;
|
||||
import org.apache.solr.client.solrj.request.QueryRequest;
|
||||
import org.apache.solr.cloud.AbstractFullDistribZkTestBase;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.apache.solr.common.cloud.SolrZkClient;
|
||||
import org.apache.solr.common.params.CoreAdminParams;
|
||||
import org.apache.solr.common.params.ModifiableSolrParams;
|
||||
import org.apache.solr.common.util.NamedList;
|
||||
import org.apache.zookeeper.KeeperException;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.Reader;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.List;
|
||||
|
||||
public class TestCloudManagedSchema extends AbstractFullDistribZkTestBase {
|
||||
|
||||
|
@ -69,72 +66,40 @@ public class TestCloudManagedSchema extends AbstractFullDistribZkTestBase {
|
|||
String collectionSchema = (String)collectionStatus.get(CoreAdminParams.SCHEMA);
|
||||
// Make sure the upgrade to managed schema happened
|
||||
assertEquals("Schema resource name differs from expected name", "managed-schema", collectionSchema);
|
||||
|
||||
// Make sure "DO NOT EDIT" is in the content of the managed schema
|
||||
String fileContent = getFileContentFromZooKeeper("managed-schema");
|
||||
assertTrue("Managed schema is missing", fileContent.contains("DO NOT EDIT"));
|
||||
|
||||
// Make sure the original non-managed schema is no longer in ZooKeeper
|
||||
assertFileNotInZooKeeper("schema.xml");
|
||||
|
||||
// Make sure the renamed non-managed schema is present in ZooKeeper
|
||||
fileContent = getFileContentFromZooKeeper("schema.xml.bak");
|
||||
assertTrue("schema file doesn't contain '<schema'", fileContent.contains("<schema"));
|
||||
}
|
||||
|
||||
private String getFileContentFromZooKeeper(String fileName) throws IOException, SolrServerException {
|
||||
QueryRequest request = new QueryRequest(params("file", fileName));
|
||||
request.setPath("/admin/file");
|
||||
RawResponseParser responseParser = new RawResponseParser();
|
||||
request.setResponseParser(responseParser);
|
||||
int which = r.nextInt(clients.size());
|
||||
// For some reason, /admin/file requests work without stripping the /collection1 step from the URL
|
||||
// (unlike /admin/cores requests - see above)
|
||||
SolrServer client = clients.get(which);
|
||||
client.request(request);
|
||||
return responseParser.getRawFileContent();
|
||||
}
|
||||
|
||||
private class RawResponseParser extends ResponseParser {
|
||||
// Stolen from ShowFileRequestHandlerTest
|
||||
private String rawFileContent = null;
|
||||
String getRawFileContent() { return rawFileContent; }
|
||||
@Override
|
||||
public String getWriterType() {
|
||||
return "mock";//unfortunately this gets put onto params wt=mock but it apparently has no effect
|
||||
}
|
||||
@Override
|
||||
public NamedList<Object> processResponse(InputStream body, String encoding) {
|
||||
try {
|
||||
rawFileContent = IOUtils.toString(body, encoding);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public NamedList<Object> processResponse(Reader reader) {
|
||||
throw new UnsupportedOperationException("TODO unimplemented");//TODO
|
||||
}
|
||||
}
|
||||
|
||||
protected final void assertFileNotInZooKeeper(String fileName) throws Exception {
|
||||
// Stolen from AbstractBadConfigTestBase
|
||||
String errString = "Not Found";
|
||||
ignoreException(Pattern.quote(errString));
|
||||
String rawContent = null;
|
||||
SolrZkClient zkClient = new SolrZkClient(zkServer.getZkHost(), 30000);
|
||||
try {
|
||||
rawContent = getFileContentFromZooKeeper(fileName);
|
||||
} catch (Exception e) {
|
||||
// short circuit out if we found what we expected
|
||||
if (-1 != e.getMessage().indexOf(errString)) return;
|
||||
// otherwise, rethrow it, possibly completely unrelated
|
||||
throw new SolrException(SolrException.ErrorCode.SERVER_ERROR,
|
||||
"Unexpected error, expected error matching: " + errString, e);
|
||||
// Make sure "DO NOT EDIT" is in the content of the managed schema
|
||||
String fileContent = getFileContentFromZooKeeper(zkClient, "/solr/configs/conf1/managed-schema");
|
||||
assertTrue("Managed schema is missing", fileContent.contains("DO NOT EDIT"));
|
||||
|
||||
// Make sure the original non-managed schema is no longer in ZooKeeper
|
||||
assertFileNotInZooKeeper(zkClient, "/solr/configs/conf1", "schema.xml");
|
||||
|
||||
// Make sure the renamed non-managed schema is present in ZooKeeper
|
||||
fileContent = getFileContentFromZooKeeper(zkClient, "/solr/configs/conf1/schema.xml.bak");
|
||||
assertTrue("schema file doesn't contain '<schema'", fileContent.contains("<schema"));
|
||||
} finally {
|
||||
resetExceptionIgnores();
|
||||
if (zkClient != null) {
|
||||
zkClient.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getFileContentFromZooKeeper(SolrZkClient zkClient, String fileName)
|
||||
throws IOException, SolrServerException, KeeperException, InterruptedException {
|
||||
|
||||
return (new String(zkClient.getData(fileName, null, null, true), "UTF-8"));
|
||||
|
||||
}
|
||||
protected final void assertFileNotInZooKeeper(SolrZkClient zkClient, String parent, String fileName) throws Exception {
|
||||
List<String> kids = zkClient.getChildren(parent, null, true);
|
||||
for (String kid : kids) {
|
||||
if (kid.equalsIgnoreCase(fileName)) {
|
||||
String rawContent = new String(zkClient.getData(fileName, null, null, true), "UTF-8");
|
||||
fail("File '" + fileName + "' was unexpectedly found in ZooKeeper. Content starts with '"
|
||||
+ rawContent.substring(0, 100) + " [...]'");
|
||||
}
|
||||
}
|
||||
fail("File '" + fileName + "' was unexpectedly found in ZooKeeper. Content starts with '"
|
||||
+ rawContent.substring(0, 100) + " [...]'");
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue