package zh.solr.se.indexer.solrproxy;
import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrCore;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
public class LocalSolrServerFactory {
private static LocalSolrServerFactory instance = new LocalSolrServerFactory();
private CoreContainer coreContainer;
// Hashtable is synchronized. HashMap is not.
private final Map<String, LocalSolrServer> serverMap = new Hashtable<String, LocalSolrServer>();
private final Logger logger;
/**
* Do not allow instantiation of this class directly.
*/
private LocalSolrServerFactory() {
logger = Logger.getLogger("solrproxy");
logger.setLevel(Level.SEVERE);
}
/**
* Get THE instance of this class.
*
* @return THE instance
*/
public static LocalSolrServerFactory getInstance() {
return instance;
}
/**
* Retrieve a local solr server (they are stored in a Map so this will always
* return the same solr server for each core)
*
* @param coreName name of the core
* @return the single solr server
* @throws UnsupportedCoreException
*/
synchronized public LocalSolrServer getLocalSolrServer(String coreName) throws UnsupportedCoreException {
// check for null core name, in case single core
if (coreName == null) {
coreName = "";
}
// check if the server instance already exists
LocalSolrServer localServer = serverMap.get(coreName);
if (localServer == null) {
localServer = createLocalSolrServer(coreName);
if (localServer != null) {
serverMap.put(coreName, localServer);
}
}
return localServer;
}
/**
* Call close() on the specified server. Remove the server from the map so
* that all references to the server return to 0 and GC can clean it up.
*
* @param coreName the name of the core
* @throws Exception
*/
synchronized public void closeSolrServer(String coreName) throws Exception {
LocalSolrServer solrServer = getLocalSolrServer(coreName);
if(solrServer != null) {
solrServer.close();
removeSolrServerFromMap(coreName);
solrServer = null;
}
}
/**
* Remove the server from the Map so references to the server return to 0 and
* the GC can clean it up. Shutdown the core container.
*
* @param coreName the name of the core.
* @throws UnsupportedCoreException
*/
synchronized private void removeSolrServerFromMap(String coreName) throws UnsupportedCoreException {
logger.log(Level.INFO, "Removing solr server '" + coreName + "' from map [size:" + serverMap.size() + "] [" + getListOfCores() + "]");
LocalSolrServer solrServer = getLocalSolrServer(coreName);
if(solrServer == null) {
logger.log(Level.INFO, "Solr server '" + coreName + "' not found in map [size:" + serverMap.size() + "] [" + getListOfCores() + "]");
}
else {
if(serverMap.remove(coreName) == null) {
logger.log(Level.SEVERE, "Remove returned nothing. Failed removing solr server '" + coreName + "' from map [size:" + serverMap.size() + "] [" + getListOfCores() + "]");
}
logger.log(Level.INFO, "Shutting down solr container for core '" + coreName);
ProxyCoreContainerFactory.getInstance().shutdownCoreContainer(coreName);
}
logger.log(Level.INFO, "Done Removing solr server '" + coreName + "' from map");
}
/**
* Return a comma-delimited list of core names currently in the map. For
* logging purposes primarily.
*
* @return list of core names
*/
private String getListOfCores() {
StringBuilder cores = new StringBuilder();
if(serverMap != null && serverMap.size() > 0) {
Set keys = serverMap.keySet();
Iterator iter = keys.iterator();
while(iter.hasNext()) {
if(cores.length() > 0) {
cores.append(", ");
}
cores.append(iter.next());
}
}
return cores.toString();
}
/**
* Create a local solr server.
*
* @param coreName the core name
* @return the local solr server
* @throws UnsupportedCoreException
*/
private LocalSolrServer createLocalSolrServer(final String coreName) throws UnsupportedCoreException {
logger.log(Level.INFO, "Creating local solr server '" + coreName + "'");
final SolrCore solrCore = getCoreContainer(coreName).getCore(coreName);
final EmbeddedSolrServer solrServer = new EmbeddedSolrServer(coreContainer, coreName);
logger.log(Level.INFO, "Created local solr server '" + coreName + "'");
return new LocalSolrServer(solrServer, solrCore);
}
/**
* Return the core container
*
* @param coreName the core name
* @return the container
* @throws UnsupportedCoreException
*/
private CoreContainer getCoreContainer(final String coreName) throws UnsupportedCoreException {
final ProxyCoreContainerFactory instance = ProxyCoreContainerFactory.getInstance();
// REMEMBER TO SET THIS VALUE ON THE INSTANCE VARIABLE OR YOU'LL HAVE A
// PROBLEM
// No index will be created and it will be difficult to track down the cause
coreContainer = instance.getCoreContainer(coreName);
return coreContainer;
}
}