View Javadoc
1   /*******************************************************************************
2    *   Gisgraphy Project 
3    * 
4    *   This library is free software; you can redistribute it and/or
5    *   modify it under the terms of the GNU Lesser General Public
6    *   License as published by the Free Software Foundation; either
7    *   version 2.1 of the License, or (at your option) any later version.
8    * 
9    *   This library is distributed in the hope that it will be useful,
10   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
11   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   *   Lesser General Public License for more details.
13   * 
14   *   You should have received a copy of the GNU Lesser General Public
15   *   License along with this library; if not, write to the Free Software
16   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
17   * 
18   *  Copyright 2008  Gisgraphy project 
19   *  David Masclet <davidmasclet@gisgraphy.com>
20   *  
21   *  
22   *******************************************************************************/
23  package com.gisgraphy.fulltext;
24  
25  import java.net.MalformedURLException;
26  import java.net.URL;
27  import java.util.logging.Level;
28  
29  import javax.xml.parsers.DocumentBuilder;
30  import javax.xml.parsers.DocumentBuilderFactory;
31  import javax.xml.xpath.XPath;
32  import javax.xml.xpath.XPathFactory;
33  
34  import org.apache.commons.httpclient.HttpClient;
35  import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager;
36  import org.apache.commons.httpclient.methods.PostMethod;
37  import org.apache.solr.client.solrj.SolrServer;
38  import org.apache.solr.client.solrj.impl.CommonsHttpSolrServer;
39  import org.apache.solr.client.solrj.response.SolrPingResponse;
40  import org.slf4j.Logger;
41  import org.slf4j.LoggerFactory;
42  import org.springframework.beans.factory.annotation.Autowired;
43  import org.springframework.beans.factory.annotation.Qualifier;
44  import org.springframework.util.Assert;
45  
46  /**
47   * Default implementation for IsolrClient.it represent a client to connect to
48   * solR server
49   * 
50   * @author <a href="mailto:david.masclet@gisgraphy.com">David Masclet</a>
51   */
52  public class SolrClient implements IsolrClient {
53  
54  
55      protected static final Logger logger = LoggerFactory
56  	    .getLogger(SolrClient.class);
57  
58      private SolrServer server;
59      
60      private MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager;
61  
62      private String URL;
63  
64      /**
65       * Default constructor needed by spring
66       */
67      public SolrClient() {
68  	super();
69      }
70  
71      /**
72       * @param solrUrl
73       *                The solr URL of the server to connect
74       */
75      @Autowired
76      public SolrClient(@Qualifier("fulltextSearchUrl")
77      String solrUrl, @Qualifier("multiThreadedHttpConnectionManager")
78      MultiThreadedHttpConnectionManager multiThreadedHttpConnectionManager) {
79  	try {
80  	    Assert.notNull(solrUrl, "solrClient does not accept null solrUrl");
81  	    Assert
82  		    .notNull(multiThreadedHttpConnectionManager,
83  			    "solrClient does not accept null multiThreadedHttpConnectionManager");
84  	    this.multiThreadedHttpConnectionManager = multiThreadedHttpConnectionManager;
85  	    this.server = new CommonsHttpSolrServer(new URL(solrUrl),
86  		    new HttpClient(multiThreadedHttpConnectionManager));
87  	    this.URL = !solrUrl.endsWith("/") ? solrUrl + "/" : solrUrl ;
88  	    logger.info("connecting to solr on " + this.URL + "...");
89  	} catch (MalformedURLException e) {
90  	    throw new RuntimeException("Error connecting to Solr! : "
91  		    + e.getMessage());
92  	}
93      }
94  
95      /*
96       * (non-Javadoc)
97       * 
98       * @see com.gisgraphy.domain.geoloc.service.fulltextsearch.IsolrClient#bindToUrl(java.lang.String)
99       */
100     public void bindToUrl(String solrUrl) {
101 	try {
102 	    this.server = new CommonsHttpSolrServer(new URL(solrUrl));
103 	    this.URL = !solrUrl.endsWith("/") ? solrUrl + "/" : solrUrl ;
104 	    logger
105 		    .info("fulltextSearchUrl for FullTextSearchEngine is changed to "
106 			    + solrUrl);
107 	} catch (Exception e) {
108 	    throw new RuntimeException("Error connecting to Solr to "+solrUrl);
109 	}
110     }
111 
112     /*
113      * (non-Javadoc)
114      * 
115      * @see com.gisgraphy.domain.geoloc.service.fulltextsearch.IsolrClient#getConnection()
116      */
117     public SolrServer getServer() {
118 	return this.server;
119     }
120 
121     /*
122      * (non-Javadoc)
123      * 
124      * @see com.gisgraphy.domain.geoloc.service.fulltextsearch.IsolrClient#getURL()
125      */
126     public String getURL() {
127 	return URL;
128     }
129 
130     public boolean isServerAlive() {
131 	try {
132 	    DocumentBuilder builder = DocumentBuilderFactory.newInstance()
133 		    .newDocumentBuilder();
134 	    XPath xpath = XPathFactory.newInstance().newXPath();
135 	    if (xpath == null || builder == null) {
136 		throw new RuntimeException(
137 			"Can not determine if fulltext engine is alive");
138 	    }
139 	    SolrPingResponse response = getServer().ping();
140 	    if (response == null) {
141 		return false;
142 	    }
143 	    return ((String) response.getResponse().get("status")).equals("OK");
144 	} catch (Exception e) {
145 	    logger.error("can not determine if fulltext engine is alive "
146 		    + e.getMessage(),e);
147 	    return false;
148 	}
149 
150     }
151 
152     /* (non-Javadoc)
153      * @see com.gisgraphy.domain.geoloc.service.fulltextsearch.IsolrClient#setSolRLogLevel(java.util.logging.Level)
154      */
155     public void setSolRLogLevel(Level level) {
156 	Assert.notNull(level, "you can not specify a null level");
157 	Assert.notNull(multiThreadedHttpConnectionManager,"httpconnectionManager should not be null, can not set log level");
158 	Assert.notNull(URL,"Solr URL should not be null, can not set log level");
159 	HttpClient client = new HttpClient(multiThreadedHttpConnectionManager);
160 	PostMethod method = new PostMethod(this.URL+"admin/logging");
161 	method.setParameter("root",level.toString().toUpperCase());
162 	method.setParameter("submit","set");
163 	 try {
164 	            try {
165 			int responseCode = client.executeMethod(method);
166 			logger.info("Set solr log Level to "+level);
167 			String responseBody = method.getResponseBodyAsString();
168 			if (responseCode >= 500){
169 			    throw new RuntimeException("Can not set solr log level to "+level+" because response code is not OK ("+responseCode+"): "+responseBody);
170 			}
171 		    } catch (Exception e) {
172 			throw new RuntimeException("Can not set solr log level to "+level,e);
173 		    }
174 	        } finally {
175 	            method.releaseConnection();
176 	        }
177     }
178 
179 }