You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ab...@apache.org on 2017/03/01 09:27:56 UTC

[48/50] [abbrv] lucene-solr:jira/solr-9858: SOLR-10134: EmbeddedSolrServer handles SchemaAPI requests

SOLR-10134: EmbeddedSolrServer handles SchemaAPI requests


Project: http://git-wip-us.apache.org/repos/asf/lucene-solr/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucene-solr/commit/0baf2fa3
Tree: http://git-wip-us.apache.org/repos/asf/lucene-solr/tree/0baf2fa3
Diff: http://git-wip-us.apache.org/repos/asf/lucene-solr/diff/0baf2fa3

Branch: refs/heads/jira/solr-9858
Commit: 0baf2fa33cef485df94649fd408c22e6430b68cf
Parents: 8b4502c
Author: Mikhail Khludnev <mk...@apache.org>
Authored: Thu Feb 23 00:40:40 2017 +0300
Committer: Mikhail Khludnev <mk...@apache.org>
Committed: Wed Mar 1 08:32:35 2017 +0300

----------------------------------------------------------------------
 solr/CHANGES.txt                                |   1 +
 .../solrj/embedded/EmbeddedSolrServer.java      |  55 +++++----
 .../solr/request/SolrQueryRequestBase.java      |  17 ++-
 .../apache/solr/servlet/SolrRequestParsers.java |  11 +-
 .../TestEmbeddedSolrServerSchemaAPI.java        | 111 +++++++++++++++++++
 .../java/org/apache/solr/SolrTestCaseJ4.java    |   6 +-
 6 files changed, 168 insertions(+), 33 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/CHANGES.txt
----------------------------------------------------------------------
diff --git a/solr/CHANGES.txt b/solr/CHANGES.txt
index 47f190b..db5e3e6 100644
--- a/solr/CHANGES.txt
+++ b/solr/CHANGES.txt
@@ -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 ==================
 

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java b/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
index fc283f4..8de5fc9 100644
--- a/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
+++ b/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
@@ -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) {

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java b/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
index 4b0e4d6..19350f0 100644
--- a/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
+++ b/solr/core/src/java/org/apache/solr/request/SolrQueryRequestBase.java
@@ -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;
   }

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
----------------------------------------------------------------------
diff --git a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
index c311d4a..93baace 100644
--- a/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
+++ b/solr/core/src/java/org/apache/solr/servlet/SolrRequestParsers.java
@@ -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

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
----------------------------------------------------------------------
diff --git a/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
new file mode 100644
index 0000000..f253831
--- /dev/null
+++ b/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServerSchemaAPI.java
@@ -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"));
+
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/lucene-solr/blob/0baf2fa3/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
----------------------------------------------------------------------
diff --git a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
index 7d9d1f6..e5bd384 100644
--- a/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
+++ b/solr/test-framework/src/java/org/apache/solr/SolrTestCaseJ4.java
@@ -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"));
   }