Skip to content

Instantly share code, notes, and snippets.

@danielbryantuk
Last active April 25, 2016 09:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save danielbryantuk/5899474 to your computer and use it in GitHub Desktop.
Save danielbryantuk/5899474 to your computer and use it in GitHub Desktop.
package uk.co.taidev.solrtesting.solr;
import com.google.common.base.Throwables;
import com.google.common.io.Files;
import com.iat.compassmassive.normalisedproductloader.springutils.SpringProfileName;
import org.apache.solr.client.solrj.SolrRequest;
import org.apache.solr.client.solrj.SolrServer;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.client.solrj.response.UpdateResponse;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.CoreDescriptor;
import org.apache.solr.core.SolrCore;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.schema.IndexSchema;
import org.apache.solr.search.SolrIndexSearcher;
import org.apache.solr.util.RefCounted;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Component;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
/**
* SolrServer sub-class that manages the life-cycle of an in-process(embedded) Solr server.
* <p/>
* Modified from original source provided by ZoomInfo @ http://browse.feedreader.com/c/ZoomInfo_Blog/12021683
* <p/>
* Required dependencies: Spring 3.2.X, Solr, 4.2.X+ (or 4.3.X), Guava 14+
* <p/>
* User: Daniel Bryant
* Date: 01/07/13
*/
@Component
@Profile(SpringProfileName.DEVELOPMENT)
public class InProcessSolrServer extends SolrServer implements Closeable {
//
//------------------ static -------------------------
//
private static final Logger LOGGER = LoggerFactory.getLogger(InProcessSolrServer.class);
private static final String DEFAULT_SOLR_HOME_DIR_PATH = "./src/test/resources/solr/";
//
//------------------ instance-------------------------
//
private File solrHomeDir = null;
private File dataDir = null;
private SolrServer delegate = null;
private transient SolrCore core = null;
//
//------------------ constructor -------------------------
//
/**
* Create an InProcessSolrServer using the default Solr Home Directory.
*/
public InProcessSolrServer() {
this(DEFAULT_SOLR_HOME_DIR_PATH);
}
/**
* Create an InProcessSolrServer using the specified Solr Home Directory and a Solr Data Directory placed
* beneath the system's temporary directory (as defined by the Guava method Files.createTempDir()).
*
* @param solrHomeDirPath path to Solr Root Directory
*/
public InProcessSolrServer(String solrHomeDirPath) {
try {
System.setProperty("solr.solr.home", solrHomeDirPath);
System.setProperty("solr.data.dir", Files.createTempDir().getAbsolutePath());
CoreContainer.Initializer initializer = new CoreContainer.Initializer();
CoreContainer coreContainer = initializer.initialize();
delegate = new EmbeddedSolrServer(coreContainer, "");
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
//
//------------------ public -------------------------
//
/**
* This method passes all queries and indexing events on to an in-process delegate.
*
* @param req Solr Request
* @return NamedList
* @throws SolrServerException if an error occurs when processing the request
* @throws IOException if an IOException occurs when processing the request
*/
@Override
public NamedList<Object> request(final SolrRequest req) throws SolrServerException, IOException {
try {
return getDelegate().request(req);
} catch (final Exception e) {
Throwables.propagateIfInstanceOf(e, SolrServerException.class);
Throwables.propagateIfInstanceOf(e, IOException.class);
throw Throwables.propagate(e);
}
}
/**
* Closes the Solr Core.
*/
@Override
public synchronized void close() {
if (core != null) {
core.close();
core = null;
}
}
/**
* SolrIndexSearcher adds schema awareness and caching functionality over the Lucene IndexSearcher.
* http://lucene.apache.org/solr/normalisedproductloader/org/apache/solr/search/SolrIndexSearcher.html
*
* @return RefCounted SolrIndexSearcher
* @throws SolrServerException
*/
public RefCounted<SolrIndexSearcher> getIndexSearcher() throws SolrServerException {
getDelegate(); // force the delegate to be created
return core.getSearcher();
}
/**
* Returns the index schema used by this Solr server.
*
* @return delegate SolrServer primary core IndexSchema
* @throws SolrServerException
*/
public IndexSchema getIndexSchema() throws SolrServerException {
getDelegate(); // force the delegate to be created
return core.getSchema();
}
/**
* Prepares this SolrServer for shutdown.
*/
@Override
public void shutdown() {
LOGGER.debug("shutdown entry...");
close();
LOGGER.debug("...core closed...");
}
@Override
public UpdateResponse addBeans(Collection<?> beans) throws SolrServerException, IOException {
UpdateResponse updateResponse = super.addBeans(beans);
super.commit();
return updateResponse;
}
@Override
public UpdateResponse deleteByQuery(String query) throws SolrServerException, IOException {
UpdateResponse updateResponse = super.deleteByQuery(query);
super.commit();
return updateResponse;
}
//
//------------------ protected -------------------------
//
@Override
@SuppressWarnings("FinalizeDeclaration")
protected void finalize() throws Throwable {
close();
super.finalize();
}
//
//------------------ private -------------------------
//
/**
* This method creates an in-process Solr server that otherwise behaves just as expected.
*/
private synchronized SolrServer getDelegate() throws SolrServerException {
if (delegate != null) {
return delegate;
}
try {
CoreContainer container = new CoreContainer(SolrResourceLoader.locateSolrHome());
CoreDescriptor descriptor = new CoreDescriptor(container, "core1", solrHomeDir.getCanonicalPath());
core = container.create(descriptor);
container.register("core1", core, false);
delegate = new EmbeddedSolrServer(container, "core1");
return delegate;
} catch (IOException ex) {
throw new SolrServerException(ex);
}
}
/**
* Sets the Solr root directory. In Solr’s documentation, this is generally referred to as "/solr-root". The "conf"
* directory (containing schema, stopwords, synonyms etc) will be a subdirectory of this.
*
* @param solrHomeDir Solr 'Home Directory'
*/
private void setSolrHomeDir(final File solrHomeDir) {
this.solrHomeDir = solrHomeDir;
System.setProperty("solr.home", solrHomeDir.getPath());
if (this.dataDir == null) {
setDataDir(new File(solrHomeDir, "data"));
}
}
/**
* Sets the Solr data directory. This is the parent directory of the "index" and "spellchecker" directories.
*
* @param dataDir Solr 'Data Directory'
*/
private void setDataDir(final File dataDir) {
this.dataDir = dataDir;
System.setProperty("solr.data.dir", dataDir.getPath());
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment