mirror of https://github.com/apache/lucene.git
SOLR-10134: EmbeddedSolrServer handles SchemaAPI requests
This commit is contained in:
parent
8b4502c218
commit
0baf2fa33c
|
@ -259,6 +259,7 @@ Other Changes
|
|||
* SOLR-10214: Remove unused HDFS BlockCache metrics and add storeFails, as well as adding total
|
||||
counts for lookups, hits, and evictions. (yonik)
|
||||
|
||||
* SOLR-10134: EmbeddedSolrServer responds on Schema API requests (Robert Alexandersson via Mikhail Khludnev)
|
||||
|
||||
================== 6.4.2 ==================
|
||||
|
||||
|
|
|
@ -172,6 +172,7 @@ public class EmbeddedSolrServer extends SolrClient {
|
|||
|
||||
req = _parser.buildRequestFrom(core, params, request.getContentStreams());
|
||||
req.getContext().put(PATH, path);
|
||||
req.getContext().put("httpMethod", request.getMethod().name());
|
||||
SolrQueryResponse rsp = new SolrQueryResponse();
|
||||
SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
|
||||
|
||||
|
@ -199,32 +200,13 @@ public class EmbeddedSolrServer extends SolrClient {
|
|||
};
|
||||
|
||||
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
new JavaBinCodec(resolver) {
|
||||
try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
createJavaBinCodec(callback, resolver).setWritableDocFields(resolver).marshal(rsp.getValues(), out);
|
||||
|
||||
@Override
|
||||
public void writeSolrDocument(SolrDocument doc) {
|
||||
callback.streamSolrDocument(doc);
|
||||
//super.writeSolrDocument( doc, fields );
|
||||
try(InputStream in = out.toInputStream()){
|
||||
return (NamedList<Object>) new JavaBinCodec(resolver).unmarshal(in);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSolrDocumentList(SolrDocumentList docs) throws IOException {
|
||||
if (docs.size() > 0) {
|
||||
SolrDocumentList tmp = new SolrDocumentList();
|
||||
tmp.setMaxScore(docs.getMaxScore());
|
||||
tmp.setNumFound(docs.getNumFound());
|
||||
tmp.setStart(docs.getStart());
|
||||
docs = tmp;
|
||||
}
|
||||
callback.streamDocListInfo(docs.getNumFound(), docs.getStart(), docs.getMaxScore());
|
||||
super.writeSolrDocumentList(docs);
|
||||
}
|
||||
|
||||
}.setWritableDocFields(resolver). marshal(rsp.getValues(), out);
|
||||
|
||||
InputStream in = out.toInputStream();
|
||||
return (NamedList<Object>) new JavaBinCodec(resolver).unmarshal(in);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
|
@ -243,6 +225,31 @@ public class EmbeddedSolrServer extends SolrClient {
|
|||
}
|
||||
}
|
||||
|
||||
private JavaBinCodec createJavaBinCodec(final StreamingResponseCallback callback, final BinaryResponseWriter.Resolver resolver) {
|
||||
return new JavaBinCodec(resolver) {
|
||||
|
||||
@Override
|
||||
public void writeSolrDocument(SolrDocument doc) {
|
||||
callback.streamSolrDocument(doc);
|
||||
//super.writeSolrDocument( doc, fields );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSolrDocumentList(SolrDocumentList docs) throws IOException {
|
||||
if (docs.size() > 0) {
|
||||
SolrDocumentList tmp = new SolrDocumentList();
|
||||
tmp.setMaxScore(docs.getMaxScore());
|
||||
tmp.setNumFound(docs.getNumFound());
|
||||
tmp.setStart(docs.getStart());
|
||||
docs = tmp;
|
||||
}
|
||||
callback.streamDocListInfo(docs.getNumFound(), docs.getStart(), docs.getMaxScore());
|
||||
super.writeSolrDocumentList(docs);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
private static void checkForExceptions(SolrQueryResponse rsp) throws Exception {
|
||||
if (rsp.getException() != null) {
|
||||
if (rsp.getException() instanceof SolrException) {
|
||||
|
|
|
@ -31,13 +31,14 @@ import org.apache.solr.common.util.ContentStream;
|
|||
import org.apache.solr.core.SolrCore;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.Principal;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
|
@ -202,7 +203,7 @@ public abstract class SolrQueryRequestBase implements SolrQueryRequest, Closeabl
|
|||
Iterable<ContentStream> contentStreams = getContentStreams();
|
||||
if (contentStreams == null) throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "No content stream");
|
||||
for (ContentStream contentStream : contentStreams) {
|
||||
parsedCommands = ApiBag.getCommandOperations(new InputStreamReader((InputStream) contentStream, UTF_8),
|
||||
parsedCommands = ApiBag.getCommandOperations(getInputStream(contentStream),
|
||||
getValidators(), validateInput);
|
||||
}
|
||||
|
||||
|
@ -211,6 +212,18 @@ public abstract class SolrQueryRequestBase implements SolrQueryRequest, Closeabl
|
|||
|
||||
}
|
||||
|
||||
private InputStreamReader getInputStream(ContentStream contentStream) {
|
||||
if(contentStream instanceof InputStream) {
|
||||
return new InputStreamReader((InputStream)contentStream, UTF_8);
|
||||
} else {
|
||||
try {
|
||||
return new InputStreamReader(contentStream.getStream(), UTF_8);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected ValidatingJsonMap getSpec() {
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
*/
|
||||
package org.apache.solr.servlet;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import static org.apache.solr.common.params.CommonParams.PATH;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
|
@ -33,13 +33,14 @@ import java.security.Principal;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
|
@ -64,8 +65,6 @@ import org.apache.solr.util.CommandOperation;
|
|||
import org.apache.solr.util.RTimerTree;
|
||||
import org.apache.solr.util.SolrFileCleaningTracker;
|
||||
|
||||
import static org.apache.solr.common.params.CommonParams.PATH;
|
||||
|
||||
|
||||
public class SolrRequestParsers
|
||||
{
|
||||
|
@ -239,7 +238,7 @@ public class SolrRequestParsers
|
|||
if (httpSolrCall != null) {
|
||||
return httpSolrCall.getCommands(validateInput);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
return super.getCommands(validateInput);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -247,7 +246,7 @@ public class SolrRequestParsers
|
|||
if (httpSolrCall != null && httpSolrCall instanceof V2HttpCall) {
|
||||
return ((V2HttpCall) httpSolrCall).getUrlParts();
|
||||
}
|
||||
return Collections.EMPTY_MAP;
|
||||
return super.getPathTemplateValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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.client.solrj.embedded;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.solr.SolrTestCaseJ4;
|
||||
import org.apache.solr.client.solrj.SolrServerException;
|
||||
import org.apache.solr.client.solrj.request.schema.SchemaRequest;
|
||||
import org.apache.solr.client.solrj.response.schema.SchemaResponse;
|
||||
import org.apache.solr.client.solrj.response.schema.SchemaResponse.FieldResponse;
|
||||
import org.apache.solr.common.SolrException;
|
||||
import org.junit.AfterClass;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestEmbeddedSolrServerSchemaAPI extends SolrTestCaseJ4 {
|
||||
|
||||
private String fieldName = "VerificationTest";
|
||||
private static EmbeddedSolrServer server;
|
||||
private final Map<String, Object> fieldAttributes;
|
||||
{
|
||||
Map<String,Object> field = new LinkedHashMap<>();
|
||||
field.put("name", fieldName);
|
||||
field.put("type", "string");
|
||||
field.put("stored", false);
|
||||
field.put("indexed", true);
|
||||
field.put("multiValued", true);
|
||||
fieldAttributes = Collections.unmodifiableMap(field);
|
||||
}
|
||||
|
||||
@BeforeClass
|
||||
public static void initClass() throws Exception {
|
||||
assertNull("no system props clash please", System.getProperty("managed.schema.mutable"));
|
||||
System.setProperty("managed.schema.mutable", ""+//true
|
||||
random().nextBoolean()
|
||||
);
|
||||
Path tmpHome = createTempDir("tmp-home");
|
||||
Path coreDir = tmpHome.resolve(DEFAULT_TEST_CORENAME);
|
||||
copyMinConf(coreDir.toFile(), null, "solrconfig-managed-schema.xml");
|
||||
initCore("solrconfig.xml" /*it's renamed to to*/, "schema.xml", tmpHome.toAbsolutePath().toString());
|
||||
|
||||
server = new EmbeddedSolrServer(h.getCoreContainer(), DEFAULT_TEST_CORENAME);
|
||||
}
|
||||
|
||||
@AfterClass
|
||||
public static void destroyClass() throws IOException {
|
||||
server.close(); // doubtful
|
||||
server = null;
|
||||
System.clearProperty("managed.schema.mutable");
|
||||
}
|
||||
|
||||
@Before
|
||||
public void thereIsNoFieldYet() throws SolrServerException, IOException{
|
||||
try{
|
||||
FieldResponse process = new SchemaRequest.Field(fieldName)
|
||||
.process(server);
|
||||
fail(""+process);
|
||||
}catch(SolrException e){
|
||||
assertTrue(e.getMessage().contains("No")
|
||||
&& e.getMessage().contains("VerificationTest"));
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaAddFieldAndVerifyExistence() throws Exception {
|
||||
assumeTrue("it needs to ammend schema", Boolean.getBoolean("managed.schema.mutable"));
|
||||
SchemaResponse.UpdateResponse addFieldResponse = new SchemaRequest.AddField(fieldAttributes).process(server);
|
||||
|
||||
assertEquals(addFieldResponse.toString(), 0, addFieldResponse.getStatus());
|
||||
|
||||
// This asserts that the field was actually created
|
||||
// this is due to the fact that the response gave OK but actually never created the field.
|
||||
Map<String,Object> foundFieldAttributes = new SchemaRequest.Field(fieldName).process(server).getField();
|
||||
assertEquals(fieldAttributes, foundFieldAttributes);
|
||||
|
||||
assertEquals("removing " + fieldName, 0,
|
||||
new SchemaRequest.DeleteField(fieldName).process(server).getStatus());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSchemaAddFieldAndFailOnImmutable() throws Exception {
|
||||
assumeFalse("it needs a readonly schema", Boolean.getBoolean("managed.schema.mutable"));
|
||||
|
||||
SchemaRequest.AddField addFieldUpdateSchemaRequest = new SchemaRequest.AddField(fieldAttributes);
|
||||
SchemaResponse.UpdateResponse addFieldResponse = addFieldUpdateSchemaRequest.process(server);
|
||||
// wt hell???? assertFalse(addFieldResponse.toString(), addFieldResponse.getStatus()==0);
|
||||
assertTrue((""+addFieldResponse).contains("schema is not editable"));
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -2019,6 +2019,10 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
// the string to write to the core.properties file may be null in which case nothing is done with it.
|
||||
// propertiesContent may be an empty string, which will actually work.
|
||||
public static void copyMinConf(File dstRoot, String propertiesContent) throws IOException {
|
||||
copyMinConf(dstRoot, propertiesContent, "solrconfig-minimal.xml");
|
||||
}
|
||||
|
||||
public static void copyMinConf(File dstRoot, String propertiesContent, String solrconfigXmlName) throws IOException {
|
||||
|
||||
File subHome = new File(dstRoot, "conf");
|
||||
if (! dstRoot.exists()) {
|
||||
|
@ -2030,7 +2034,7 @@ public abstract class SolrTestCaseJ4 extends LuceneTestCase {
|
|||
}
|
||||
String top = SolrTestCaseJ4.TEST_HOME() + "/collection1/conf";
|
||||
FileUtils.copyFile(new File(top, "schema-tiny.xml"), new File(subHome, "schema.xml"));
|
||||
FileUtils.copyFile(new File(top, "solrconfig-minimal.xml"), new File(subHome, "solrconfig.xml"));
|
||||
FileUtils.copyFile(new File(top, solrconfigXmlName), new File(subHome, "solrconfig.xml"));
|
||||
FileUtils.copyFile(new File(top, "solrconfig.snippet.randomindexconfig.xml"), new File(subHome, "solrconfig.snippet.randomindexconfig.xml"));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue