001package org.kuali.ole.docstore.discovery.service;
002
003import java.io.File;
004import java.io.IOException;
005import java.net.MalformedURLException;
006import java.util.HashMap;
007import java.util.Map;
008
009import javax.xml.parsers.ParserConfigurationException;
010
011import org.apache.commons.lang.StringUtils;
012import org.apache.solr.client.solrj.SolrServer;
013import org.apache.solr.client.solrj.SolrServerException;
014import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
015import org.apache.solr.client.solrj.impl.ConcurrentUpdateSolrServer;
016import org.apache.solr.client.solrj.impl.HttpSolrServer;
017import org.apache.solr.client.solrj.impl.XMLResponseParser;
018import org.apache.solr.core.CoreContainer;
019import org.kuali.rice.core.api.config.property.ConfigContext;
020import org.slf4j.Logger;
021import org.slf4j.LoggerFactory;
022import org.xml.sax.SAXException;
023
024/**
025 * This class handles the creation of solr server object, used for connecting to solr server (core).
026 * User: tirumalesh.b
027 * Date: 23/12/11 Time: 12:32 PM
028 */
029public class SolrServerManager {
030
031    private static final Logger LOG = LoggerFactory.getLogger(SolrServerManager.class);
032
033    public static final String SOLR_HOME = "solr.solr.home";
034    public static final String SOLR_CORE_MAIN = "bib";
035    public static final String SOLR_SERVER_EMBEDDED = "solr.server.embedded";
036    public static final String SOLR_SERVER_STREAMING = "solr.server.streaming";
037
038    private static SolrServerManager solrServerMgr = null;
039    private static String docSearchUrl = null;
040    public static Map<String, SolrServer> serverMap = null;
041
042    public static SolrServerManager getInstance() {
043        if (null == solrServerMgr) {
044            solrServerMgr = new SolrServerManager();
045        }
046        return solrServerMgr;
047    }
048
049    private SolrServerManager() {
050        init();
051    }
052
053    protected void init() {
054        LOG.debug("SolrServerManager.init()");
055        if(ConfigContext.getCurrentContextConfig()!=null){
056            docSearchUrl = ConfigContext.getCurrentContextConfig().getProperty("docSearchURL");
057        }
058        if ((null != docSearchUrl) && !docSearchUrl.endsWith("/")) {
059            docSearchUrl = docSearchUrl + "/";
060        }
061        LOG.info("Actual Document Search URL being used docSearchURL=" + docSearchUrl);
062        serverMap = new HashMap<String, SolrServer>();
063    }
064
065    /**
066     * Simplest method to get a solr server for the default core.
067     *
068     * @return Returns solr server object.
069     * @throws Exception Throws an exception on error.
070     */
071    public SolrServer getSolrServer() throws SolrServerException {
072        return getSolrServer(SOLR_CORE_MAIN);
073    }
074
075    /**
076     * Get a solr server for the given core.
077     *
078     * @param solrCore Solr core for which server is required.
079     * @return Returns solr server object.
080     * @throws Exception Throws an exception on error.
081     */
082    public SolrServer getSolrServer(String solrCore) throws SolrServerException {
083        boolean isStreaming = false;
084        boolean isEmbedded = false;
085        String embedPropValue = System.getProperty(SOLR_SERVER_EMBEDDED);
086        if (StringUtils.isNotEmpty(embedPropValue)) {
087            isEmbedded = Boolean.parseBoolean(embedPropValue);
088        }
089        String streamingPropValue = System.getProperty(SOLR_SERVER_STREAMING);
090        if (StringUtils.isNotEmpty(streamingPropValue)) {
091            isStreaming = Boolean.parseBoolean(streamingPropValue);
092        }
093        return getSolrServer(solrCore, isStreaming, isEmbedded);
094    }
095
096    /**
097     * Get a solr server for the given core, with the specified options for streaming or embedded.
098     * The streaming and embedded options are considered only for the first time, for the sake of simplicity.
099     * The server objects are saved in a map and reused.
100     *
101     * @param solrCore    Solr core for which server is required.
102     * @param isStreaming Indicates whether a streaming server is needed.
103     * @param isEmbedded  Indicates whether an embedded server is needed.
104     * @return Returns solr server object.
105     * @throws Exception Throws an exception on error.
106     */
107    public SolrServer getSolrServer(String solrCore, boolean isStreaming, boolean isEmbedded)
108            throws SolrServerException {
109        SolrServer solr = null;
110        try {
111            if (null == serverMap) {
112                serverMap = new HashMap<String, SolrServer>();
113            }
114            solr = serverMap.get(solrCore);
115            if (null != solr) {
116                return solr;
117            }
118            if (isEmbedded) {
119                solr = getEmbeddedSolrServer(solrCore);
120            } else if (isStreaming) {
121                solr = new ConcurrentUpdateSolrServer(docSearchUrl + solrCore, 100, 5);
122            } else {
123                solr = getCommonsHttpSolrServer(docSearchUrl + solrCore);
124            }
125            serverMap.put(solrCore, solr);
126        } catch (SolrServerException sse) {
127            throw sse;
128        } catch (Exception e) {
129            throw new SolrServerException(e);
130        }
131        return solr;
132    }
133
134    public String getSolrCoreURL() {
135        return docSearchUrl + SOLR_CORE_MAIN;
136    }
137
138    protected static HttpSolrServer getCommonsHttpSolrServer(String solrUrl) throws MalformedURLException {
139        HttpSolrServer server = new HttpSolrServer(solrUrl);
140        server.setConnectionTimeout(100);
141        server.setDefaultMaxConnectionsPerHost(100);
142        server.setMaxTotalConnections(100);
143        server.setFollowRedirects(false);
144        server.setAllowCompression(true);
145        server.setMaxRetries(1);
146        server.setParser(new XMLResponseParser());
147        return server;
148    }
149
150    protected SolrServer getEmbeddedSolrServer(String solrCore) throws IOException, ParserConfigurationException, SAXException, SolrServerException {
151        String solrHomeDir = System.getProperty(SOLR_HOME);
152        File home = new File(solrHomeDir);
153        File f = new File(home, "solr.xml");
154        CoreContainer container = new CoreContainer();
155        container.load();
156        return new EmbeddedSolrServer(container, solrCore);
157    }
158
159}