You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by ro...@apache.org on 2015/03/26 10:21:01 UTC

svn commit: r1669305 - in /lucene/dev/trunk/solr: ./ core/src/java/org/apache/solr/client/solrj/embedded/ core/src/java/org/apache/solr/core/ core/src/test/org/apache/solr/ core/src/test/org/apache/solr/client/solrj/embedded/ core/src/test/org/apache/s...

Author: romseygeek
Date: Thu Mar 26 09:21:01 2015
New Revision: 1669305

URL: http://svn.apache.org/r1669305
Log:
SOLR-7307: Add constructors to EmbeddedSolrServer taking Path or NodeConfig

Added:
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServer.java   (with props)
Modified:
    lucene/dev/trunk/solr/CHANGES.txt
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
    lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java
    lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java

Modified: lucene/dev/trunk/solr/CHANGES.txt
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/CHANGES.txt?rev=1669305&r1=1669304&r2=1669305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/CHANGES.txt (original)
+++ lucene/dev/trunk/solr/CHANGES.txt Thu Mar 26 09:21:01 2015
@@ -208,6 +208,9 @@ New Features
     json.facet={ salary_percentiles : "percentile(salary,25,50,75)" }
   (yonik)
 
+* SOLR-7307: EmbeddedSolrServer can now be started up by passing a path to a
+  solr home directory, or a NodeConfig object (Alan Woodward, Mike Drob)
+
 Bug Fixes
 ----------------------
 

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java?rev=1669305&r1=1669304&r2=1669305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/client/solrj/embedded/EmbeddedSolrServer.java Thu Mar 26 09:21:01 2015
@@ -31,7 +31,9 @@ import org.apache.solr.common.params.Sol
 import org.apache.solr.common.util.JavaBinCodec;
 import org.apache.solr.common.util.NamedList;
 import org.apache.solr.core.CoreContainer;
+import org.apache.solr.core.NodeConfig;
 import org.apache.solr.core.SolrCore;
+import org.apache.solr.core.SolrXmlConfig;
 import org.apache.solr.request.SolrQueryRequest;
 import org.apache.solr.request.SolrRequestHandler;
 import org.apache.solr.request.SolrRequestInfo;
@@ -44,174 +46,212 @@ import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Path;
 
 /**
- * SolrClient that connects directly to SolrCore.
- * <p>
- * TODO -- this implementation sends the response to XML and then parses it.  
- * It *should* be able to convert the response directly into a named list.
- * 
+ * SolrClient that connects directly to a CoreContainer.
  *
  * @since solr 1.3
  */
-public class EmbeddedSolrServer extends SolrClient
-{
+public class EmbeddedSolrServer extends SolrClient {
+
   protected final CoreContainer coreContainer;
   protected final String coreName;
   private final SolrRequestParsers _parser;
-  
+
   /**
-   * Use the other constructor using a CoreContainer and a name.
+   * Create an EmbeddedSolrServer using a given solr home directory
+   *
+   * @param solrHome        the solr home directory
+   * @param defaultCoreName the core to route requests to by default
    */
-  public EmbeddedSolrServer(SolrCore core)
-  {
+  public EmbeddedSolrServer(Path solrHome, String defaultCoreName) {
+    this(load(new CoreContainer(SolrXmlConfig.fromSolrHome(solrHome))), defaultCoreName);
+  }
+
+  /**
+   * Create an EmbeddedSolrServer using a NodeConfig
+   *
+   * @param nodeConfig      the configuration
+   * @param defaultCoreName the core to route requests to be default
+   */
+  public EmbeddedSolrServer(NodeConfig nodeConfig, String defaultCoreName) {
+    this(load(new CoreContainer(nodeConfig)), defaultCoreName);
+  }
+
+  private static CoreContainer load(CoreContainer cc) {
+    cc.load();
+    return cc;
+  }
+
+  /**
+   * Create an EmbeddedSolrServer wrapping a particular SolrCore
+   */
+  public EmbeddedSolrServer(SolrCore core) {
     this(core.getCoreDescriptor().getCoreContainer(), core.getName());
   }
-    
+
   /**
-   * Creates a SolrServer.
+   * Create an EmbeddedSolrServer wrapping a CoreContainer.
+   * <p>
+   * Note that EmbeddedSolrServer will shutdown the wrapped CoreContainer when
+   * {@link #close()} is called.
+   *
    * @param coreContainer the core container
-   * @param coreName the core name
+   * @param coreName      the core to route requests to be default
    */
-  public EmbeddedSolrServer(CoreContainer coreContainer, String coreName)
-  {
-    if ( coreContainer == null ) {
+  public EmbeddedSolrServer(CoreContainer coreContainer, String coreName) {
+    if (coreContainer == null) {
       throw new NullPointerException("CoreContainer instance required");
     }
     if (Strings.isNullOrEmpty(coreName))
       throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "Core name cannot be empty");
     this.coreContainer = coreContainer;
     this.coreName = coreName;
-    _parser = new SolrRequestParsers( null );
+    _parser = new SolrRequestParsers(null);
   }
-  
+
+  // TODO-- this implementation sends the response to XML and then parses it.
+  // It *should* be able to convert the response directly into a named list.
+
   @Override
-  public NamedList<Object> request(SolrRequest request, String coreName) throws SolrServerException, IOException
-  {
+  public NamedList<Object> request(SolrRequest request, String coreName) throws SolrServerException, IOException {
+
     String path = request.getPath();
-    if( path == null || !path.startsWith( "/" ) ) {
+    if (path == null || !path.startsWith("/")) {
       path = "/select";
     }
 
+    SolrRequestHandler handler = coreContainer.getRequestHandler(path);
+    if (handler != null) {
+      try {
+        SolrQueryRequest req = _parser.buildRequestFrom(null, request.getParams(), request.getContentStreams());
+        SolrQueryResponse resp = new SolrQueryResponse();
+        handler.handleRequest(req, resp);
+        checkForExceptions(resp);
+        return BinaryResponseWriter.getParsedResponse(req, resp);
+      } catch (IOException | SolrException iox) {
+        throw iox;
+      } catch (Exception ex) {
+        throw new SolrServerException(ex);
+      }
+    }
+
     if (coreName == null)
       coreName = this.coreName;
 
     // Check for cores action
-    SolrCore core =  coreContainer.getCore( coreName );
-    if( core == null ) {
-      throw new SolrException( SolrException.ErrorCode.SERVER_ERROR, 
-                               "No such core: " + coreName );
-    }
-    
-    SolrParams params = request.getParams();
-    if( params == null ) {
-      params = new ModifiableSolrParams();
-    }
-    
-    // Extract the handler from the path or params
-    SolrRequestHandler handler = core.getRequestHandler( path );
-    if( handler == null ) {
-      if( "/select".equals( path ) || "/select/".equalsIgnoreCase( path) ) {
-        String qt = params.get( CommonParams.QT );
-        handler = core.getRequestHandler( qt );
-        if( handler == null ) {
-          throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+qt);
+    SolrQueryRequest req = null;
+    try (SolrCore core = coreContainer.getCore(coreName)) {
+
+      if (core == null) {
+        throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "No such core: " + coreName);
+      }
+
+      SolrParams params = request.getParams();
+      if (params == null) {
+        params = new ModifiableSolrParams();
+      }
+
+      // Extract the handler from the path or params
+      handler = core.getRequestHandler(path);
+      if (handler == null) {
+        if ("/select".equals(path) || "/select/".equalsIgnoreCase(path)) {
+          String qt = params.get(CommonParams.QT);
+          handler = core.getRequestHandler(qt);
+          if (handler == null) {
+            throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "unknown handler: " + qt);
+          }
         }
       }
-      // Perhaps the path is to manage the cores
+
       if (handler == null) {
-        handler = coreContainer.getRequestHandler(path);
+        throw new SolrException(SolrException.ErrorCode.BAD_REQUEST, "unknown handler: " + path);
       }
-    }
-    if( handler == null ) {
-      core.close();
-      throw new SolrException( SolrException.ErrorCode.BAD_REQUEST, "unknown handler: "+path );
-    }
 
-    SolrQueryRequest req = null;
-    try {
-      req = _parser.buildRequestFrom( core, params, request.getContentStreams() );
-      req.getContext().put( "path", path );
+      req = _parser.buildRequestFrom(core, params, request.getContentStreams());
+      req.getContext().put("path", path);
       SolrQueryResponse rsp = new SolrQueryResponse();
       SolrRequestInfo.setRequestInfo(new SolrRequestInfo(req, rsp));
-      
-      core.execute( handler, req, rsp );
-      if( rsp.getException() != null ) {
-        if(rsp.getException() instanceof SolrException) {
-          throw rsp.getException();
-        }
-        throw new SolrServerException( rsp.getException() );
-      }
-      
+
+      core.execute(handler, req, rsp);
+      checkForExceptions(rsp);
+
       // Check if this should stream results
-      if( request.getStreamingResponseCallback() != null ) {
+      if (request.getStreamingResponseCallback() != null) {
         try {
           final StreamingResponseCallback callback = request.getStreamingResponseCallback();
-          BinaryResponseWriter.Resolver resolver = 
-            new BinaryResponseWriter.Resolver( req, rsp.getReturnFields()) 
-          {
-            @Override
-            public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException {
-              // write an empty list...
-              SolrDocumentList docs = new SolrDocumentList();
-              docs.setNumFound( ctx.docs.matches() );
-              docs.setStart( ctx.docs.offset() );
-              docs.setMaxScore( ctx.docs.maxScore() );
-              codec.writeSolrDocumentList( docs );
-              
-              // This will transform
-              writeResultsBody( ctx, codec );
-            }
-          };
-          
+          BinaryResponseWriter.Resolver resolver =
+              new BinaryResponseWriter.Resolver(req, rsp.getReturnFields()) {
+                @Override
+                public void writeResults(ResultContext ctx, JavaBinCodec codec) throws IOException {
+                  // write an empty list...
+                  SolrDocumentList docs = new SolrDocumentList();
+                  docs.setNumFound(ctx.docs.matches());
+                  docs.setStart(ctx.docs.offset());
+                  docs.setMaxScore(ctx.docs.maxScore());
+                  codec.writeSolrDocumentList(docs);
+
+                  // This will transform
+                  writeResultsBody(ctx, codec);
+                }
+              };
+
 
           ByteArrayOutputStream out = new ByteArrayOutputStream();
           new JavaBinCodec(resolver) {
 
             @Override
             public void writeSolrDocument(SolrDocument doc) {
-              callback.streamSolrDocument( doc );
+              callback.streamSolrDocument(doc);
               //super.writeSolrDocument( doc, fields );
             }
 
             @Override
             public void writeSolrDocumentList(SolrDocumentList docs) throws IOException {
-              if( docs.size() > 0 ) {
+              if (docs.size() > 0) {
                 SolrDocumentList tmp = new SolrDocumentList();
-                tmp.setMaxScore( docs.getMaxScore() );
-                tmp.setNumFound( docs.getNumFound() );
-                tmp.setStart( docs.getStart() );
+                tmp.setMaxScore(docs.getMaxScore());
+                tmp.setNumFound(docs.getNumFound());
+                tmp.setStart(docs.getStart());
                 docs = tmp;
               }
-              callback.streamDocListInfo( docs.getNumFound(), docs.getStart(), docs.getMaxScore() );
+              callback.streamDocListInfo(docs.getNumFound(), docs.getStart(), docs.getMaxScore());
               super.writeSolrDocumentList(docs);
             }
-            
+
           }.marshal(rsp.getValues(), out);
 
           InputStream in = new ByteArrayInputStream(out.toByteArray());
           return (NamedList<Object>) new JavaBinCodec(resolver).unmarshal(in);
-        }
-        catch (Exception ex) {
+        } catch (Exception ex) {
           throw new RuntimeException(ex);
         }
       }
-      
+
       // Now write it out
       NamedList<Object> normalized = BinaryResponseWriter.getParsedResponse(req, rsp);
       return normalized;
-    } catch( IOException | SolrException iox ) {
+    } catch (IOException | SolrException iox) {
       throw iox;
-    } catch( Exception ex ) {
-      throw new SolrServerException( ex );
-    }
-    finally {
+    } catch (Exception ex) {
+      throw new SolrServerException(ex);
+    } finally {
       if (req != null) req.close();
-      core.close();
       SolrRequestInfo.clearRequestInfo();
     }
   }
-  
+
+  private static void checkForExceptions(SolrQueryResponse rsp) throws Exception {
+    if (rsp.getException() != null) {
+      if (rsp.getException() instanceof SolrException) {
+        throw rsp.getException();
+      }
+      throw new SolrServerException(rsp.getException());
+    }
+
+  }
+
   /**
    * Shutdown all cores within the EmbeddedSolrServer instance
    */
@@ -219,9 +259,10 @@ public class EmbeddedSolrServer extends
   public void close() throws IOException {
     coreContainer.shutdown();
   }
-  
+
   /**
    * Getter method for the CoreContainer
+   *
    * @return the core container
    */
   public CoreContainer getCoreContainer() {

Modified: lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java?rev=1669305&r1=1669304&r2=1669305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java (original)
+++ lucene/dev/trunk/solr/core/src/java/org/apache/solr/core/SolrXmlConfig.java Thu Mar 26 09:21:01 2015
@@ -39,6 +39,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Path;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Properties;
@@ -137,6 +138,11 @@ public class SolrXmlConfig {
     return fromFile(loader, new File(solrHome, SOLR_XML_FILE));
   }
 
+  public static NodeConfig fromSolrHome(Path solrHome) {
+    SolrResourceLoader loader = new SolrResourceLoader(solrHome.toString());
+    return fromSolrHome(loader, solrHome.toString());
+  }
+
   private static void checkForIllegalConfig(Config config) {
     failIfFound(config, "solr/@coreLoadThreads");
     failIfFound(config, "solr/@persistent");

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java?rev=1669305&r1=1669304&r2=1669305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/AnalysisAfterCoreReloadTest.java Thu Mar 26 09:21:01 2015
@@ -17,12 +17,9 @@ package org.apache.solr;
  * limitations under the License.
  */
 
-import java.io.File;
-import java.io.IOException;
-
 import org.apache.commons.io.FileUtils;
-import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.SolrClient;
+import org.apache.solr.client.solrj.SolrQuery;
 import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
 import org.apache.solr.client.solrj.request.AbstractUpdateRequest.ACTION;
 import org.apache.solr.client.solrj.request.QueryRequest;
@@ -32,6 +29,9 @@ import org.apache.solr.core.SolrCore;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
 
+import java.io.File;
+import java.io.IOException;
+
 public class AnalysisAfterCoreReloadTest extends SolrTestCaseJ4 {
   
   private static String tmpSolrHome;
@@ -138,7 +138,7 @@ public class AnalysisAfterCoreReloadTest
   }
 
   protected SolrClient getSolrCore() {
-    return new EmbeddedSolrServer(h.getCore());
+    return new EmbeddedSolrServer(h.getCoreContainer(), collection);
   }
 
 }

Added: lucene/dev/trunk/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServer.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServer.java?rev=1669305&view=auto
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServer.java (added)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/client/solrj/embedded/TestEmbeddedSolrServer.java Thu Mar 26 09:21:01 2015
@@ -0,0 +1,69 @@
+package org.apache.solr.client.solrj.embedded;
+
+/*
+ * 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.
+ */
+
+import org.apache.solr.SolrTestCaseJ4;
+import org.apache.solr.client.solrj.SolrQuery;
+import org.apache.solr.client.solrj.request.CoreAdminRequest;
+import org.apache.solr.common.SolrInputDocument;
+import org.apache.solr.core.NodeConfig;
+import org.apache.solr.core.SolrResourceLoader;
+import org.junit.Test;
+
+import java.io.IOException;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+
+public class TestEmbeddedSolrServer extends SolrTestCaseJ4 {
+
+  @Test
+  public void testPathConstructor() throws IOException {
+    Path path = Paths.get(TEST_HOME());
+    try (EmbeddedSolrServer server = new EmbeddedSolrServer(path, "collection1")) {
+
+    }
+  }
+
+  @Test
+  public void testNodeConfigConstructor() throws Exception {
+    Path path = createTempDir();
+
+    SolrResourceLoader loader = new SolrResourceLoader(path.toString());
+    NodeConfig config = new NodeConfig.NodeConfigBuilder("testnode", loader)
+        .setConfigSetBaseDirectory(Paths.get(TEST_HOME()).resolve("configsets").toString())
+        .build();
+
+    try (EmbeddedSolrServer server = new EmbeddedSolrServer(config, "newcore")) {
+
+      CoreAdminRequest.Create createRequest = new CoreAdminRequest.Create();
+      createRequest.setCoreName("newcore");
+      createRequest.setConfigSet("minimal");
+      server.request(createRequest);
+
+      SolrInputDocument doc = new SolrInputDocument();
+      doc.addField("articleid", "test");
+      server.add("newcore", doc);
+      server.commit();
+
+      assertEquals(1, server.query(new SolrQuery("*:*")).getResults().getNumFound());
+      assertEquals(1, server.query("newcore", new SolrQuery("*:*")).getResults().getNumFound());
+
+    }
+  }
+
+}

Modified: lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java
URL: http://svn.apache.org/viewvc/lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java?rev=1669305&r1=1669304&r2=1669305&view=diff
==============================================================================
--- lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java (original)
+++ lucene/dev/trunk/solr/core/src/test/org/apache/solr/request/TestIntervalFaceting.java Thu Mar 26 09:21:01 2015
@@ -17,9 +17,6 @@
 
 package org.apache.solr.request;
 
-import java.util.Arrays;
-import java.util.Comparator;
-
 import org.apache.lucene.util.BytesRef;
 import org.apache.solr.SolrTestCaseJ4;
 import org.apache.solr.client.solrj.SolrClient;
@@ -39,6 +36,9 @@ import org.apache.solr.util.RefCounted;
 import org.junit.BeforeClass;
 import org.junit.Test;
 
+import java.util.Arrays;
+import java.util.Comparator;
+
 public class TestIntervalFaceting extends SolrTestCaseJ4 {
 
   @BeforeClass
@@ -905,7 +905,7 @@ public class TestIntervalFaceting extend
     
     // Don't close this client, it would shutdown the CoreContainer
     @SuppressWarnings("resource")
-    SolrClient client = new EmbeddedSolrServer(h.getCore());
+    SolrClient client = new EmbeddedSolrServer(h.getCoreContainer(), h.coreName);
     
     SolrQuery q = new SolrQuery();
     q.setQuery("*:*");