source: gs3-extensions/solr/trunk/src/src/java/org/greenstone/gsdl3/service/SolrSearch.java@ 29355

Last change on this file since 29355 was 29355, checked in by ak19, 10 years ago

Overlooked a very important commit, but with corrections: solr cores should not be removed for solr/lucene 4.7.2 as they were for lucene/solr 3.3.0. However, all the solr cores do need to be shutdown on cleanUp() in order to not have the running GS3 server hold a lock on any of the cores, as this will prevent the GS3 tomcat from stopping fully, with part of tomcat still running in the background even if it looks like tomcat has stopped.

  • Property svn:executable set to *
File size: 8.9 KB
Line 
1package org.greenstone.gsdl3.service;
2
3
4// Based on LuceneSearch, but not thoroughly tested
5
6// Greenstone classes
7import org.greenstone.gsdl3.util.*;
8import org.greenstone.util.GlobalProperties;
9
10// XML classes
11import org.w3c.dom.Element;
12import org.w3c.dom.Document;
13import org.w3c.dom.NodeList;
14
15import java.util.HashMap;
16import java.util.ArrayList;
17import java.util.Iterator;
18
19
20import org.apache.solr.client.solrj.SolrQuery;
21import org.apache.solr.client.solrj.SolrServer;
22import org.apache.solr.client.solrj.SolrServerException;
23import org.apache.solr.client.solrj.embedded.EmbeddedSolrServer;
24import org.apache.solr.client.solrj.response.QueryResponse;
25import org.apache.solr.common.SolrDocument;
26import org.apache.solr.common.SolrDocumentList;
27import org.apache.solr.common.params.ModifiableSolrParams;
28import org.apache.solr.common.params.SolrParams;
29import org.apache.solr.common.util.NamedList;
30import org.apache.solr.servlet.SolrRequestParsers;
31import org.apache.solr.core.CoreContainer;
32import org.apache.solr.core.SolrCore;
33
34import java.io.File;
35import java.util.Collection;
36
37
38import org.apache.log4j.*;
39
40
41public class SolrSearch extends LuceneSearch {
42
43 static Logger logger = Logger.getLogger(org.greenstone.gsdl3.service.SolrSearch.class.getName());
44
45 static protected CoreContainer solr_cores = null;
46 protected HashMap solr_server;
47
48 public SolrSearch()
49 {
50 solr_server = new HashMap();
51
52 if (solr_cores == null) {
53 // Share one CoreContainer across all sites/collections
54 try {
55
56 String gsdl3_home = GlobalProperties.getGSDL3Home();
57 String solr_ext_name = GlobalProperties.getProperty("gsdlext.solr.dirname","solr");
58
59 String solr_home_str = GSFile.extHome(gsdl3_home,solr_ext_name);
60
61 solr_cores = new CoreContainer(solr_home_str);
62 }
63 catch (Exception e) {
64 e.printStackTrace();
65 }
66 }
67 }
68
69
70 // Overriding the cleanUp() method here, so as to parallel the structure of GS2SolrSearch
71 // which also calls shutdown() on its CoreContainer object in GS2SolrSearch.cleanUp().
72 // However, this class has not yet been tested, so it's not certain that this method is
73 // required here.
74 // Adjusted to bring it up to speed with changes in GS2SolrSearch (for activate.pl) - not yet tested
75 public void cleanUp() {
76 super.cleanUp();
77
78 // 1. clear the map keeping track of the solrcores' EmbeddedSolrServers in this collection
79 solr_server.clear();
80
81 // 2. Need GS3 server (tomcat) to release the cores, else a part of tomcat is still running in the background
82 // on ant stop, holding a lock on the cores. Doing shutdown() preserves core descriptions in solr.xml
83 solr_cores.shutdown();
84 solr_cores = null;
85
86 // For solr 3.3.0's jetty server, but not for solr 4.7.2's jetty server
87 /*
88 // 2. Remove all SolrCores in the CoreContainer (solr_cores) that are specific to this collection
89 String collection_core_name_prefix = getCollectionCoreNamePrefix();
90
91 Collection<String> coreNames = solr_cores.getCoreNames();
92 if(!coreNames.isEmpty()) {
93 Iterator<String> coreIterator = coreNames.iterator();
94 while(coreIterator.hasNext()) {
95
96 String solrCoreName = coreIterator.next();
97 if(solrCoreName.startsWith(collection_core_name_prefix)) {
98
99 logger.error("**** Removing collection-specific core: " + solrCoreName + " from CoreContainer");
100
101 // CoreContainer.remove(String name): removes and returns registered core w/o decrementing it's reference count
102 // http://lucene.apache.org/solr/api/index.html?org/apache/solr/core/CoreContainer.html
103 SolrCore solr_core = solr_cores.remove(solrCoreName);
104 while(!solr_core.isClosed()) {
105 logger.error("@@@@@@ " + solrCoreName + " was not closed. Closing....");
106 solr_core.close(); // http://lucene.apache.org/solr/api/org/apache/solr/core/SolrCore.html
107 }
108 if(solr_core.isClosed()) {
109 logger.error("@@@@@@ " + solrCoreName + " is closed.");
110 }
111 solr_core = null;
112 }
113 }
114 }
115
116 // 3. if there are no more solr cores in Greenstone, then solr_cores will be empty, null the CoreContainer
117 // All going well, this will happen when we're ant stopping the Greenstone server and the last Solr collection
118 // is being deactivated
119 Collection<String> coreNamesRemaining = solr_cores.getCoreNames();
120 if(coreNamesRemaining.isEmpty()) {
121 logger.error("**** CoreContainer contains 0 solrCores. Shutting down...");
122
123 solr_cores.shutdown(); // wouldn't do anything anyway for 0 cores I think
124 solr_cores = null;
125 }
126 else { // else part is just for debugging
127 Iterator coreIterator = coreNamesRemaining.iterator();
128 while(coreIterator.hasNext()) {
129 logger.error("**** Core: " + coreIterator.next() + " still exists in CoreContainer");
130 }
131 }
132 */
133 }
134
135
136 // adjusted configure to bring it up to speed with changes in GS2SolrSearch (for activate.pl) - not yet tested
137 public boolean configure(Element info, Element extra_info) {
138 boolean success = super.configure(info, extra_info);
139
140 // 1. Make the CoreContainer reload solr.xml
141 // This is particularly needed for when activate.pl is executed during
142 // a running GS3 server. At that point, the solr collection is reactivated and
143 // we need to tell Greenstone that the solr index has changed. This requires
144 // the CoreContainer to reload the solr.xml file, and it all works again.
145
146 solr_server.clear(); // clear the map of solr cores for this collection added to the map upon querying
147
148 // Reload the updated solr.xml into the CoreContainer
149 // (Doing a solr_cores.shutdown() first doesn't seem to be required)
150 try {
151 String solr_home_str = solr_cores.getSolrHome();
152 File solr_home = new File(solr_home_str);
153 File solr_xml = new File( solr_home,"solr.xml" );
154
155 //solr_cores.load(solr_home_str,solr_xml);
156 solr_cores.load();
157 } catch (Exception e) {
158 logger.error("Exception in SolrSearch.configure(): " + e.getMessage());
159 e.printStackTrace();
160 return false;
161 }
162
163 // initialize required number of SolrCores based on values
164 // in 'index_ids' that are set by LuceneSearch::configure()
165
166 String core_name_prefix = getCollectionCoreNamePrefix();
167
168 for (int i=0; i<index_ids.size(); i++) {
169
170 String idx_name = (String)index_ids.get(i);
171 String core_name = core_name_prefix + "-" + idx_name;
172
173 EmbeddedSolrServer solr_core
174 = new EmbeddedSolrServer(solr_cores,core_name);
175
176 solr_server.put(core_name,solr_core);
177 }
178
179 return success;
180 }
181
182 protected void getIndexData(ArrayList index_ids, ArrayList index_names, String lang)
183 {
184 }
185
186 /** Process a text query - implemented by concrete subclasses */
187 protected Element processTextQuery(Element request) {
188
189 Document result_doc = XMLConverter.newDOM();
190 Element result = result_doc.createElement(GSXML.RESPONSE_ELEM);
191 Element doc_node_list = result_doc.createElement(GSXML.DOC_NODE_ELEM+GSXML.LIST_MODIFIER);
192 Element metadata_list = result_doc.createElement(GSXML.METADATA_ELEM+GSXML.LIST_MODIFIER);
193 initResultElement(result,doc_node_list,metadata_list);
194
195 if (!hasParamList(request,metadata_list)) {
196 return result;
197 }
198
199 Element param_list = (Element) GSXML.getChildByTagName(request, GSXML.PARAM_ELEM+GSXML.LIST_MODIFIER);
200 if (!hasQueryString(param_list,metadata_list)) {
201 return result;
202 }
203
204 HashMap params = GSXML.extractParams(param_list, false);
205 String query_string = (String) params.get(QUERY_PARAM);
206
207
208 // Get the index
209 String index = (String) params.get(INDEX_PARAM);
210 if (index == null || index.equals("")) {
211 index = this.default_index; // assume the default
212 }
213
214 try {
215
216 ModifiableSolrParams solrParams = new ModifiableSolrParams();
217 solrParams.set("q", query_string);
218 //solrParams.set("start", start);
219 //solrParams.set("rows", nbDocuments);
220
221 String core_name = getCollectionCoreNamePrefix() + "-" + index;
222
223 EmbeddedSolrServer solr_core = (EmbeddedSolrServer)solr_server.get(core_name);
224
225 QueryResponse solrResponse = solr_core.query(solrParams);
226
227 SolrDocumentList hits = solrResponse.getResults();
228
229 if (hits != null) {
230 // or should this be docs.getNumFound() ??
231 GSXML.addMetadata(metadata_list, "numDocsMatched", ""+hits.size());
232
233 System.err.println(hits.getNumFound() + " documents found, "
234 + hits.size() + " returned : ");
235
236 for (int i = 0; i < hits.size(); i++) {
237 SolrDocument solr_doc = hits.get(i);
238
239 String node_id = (String)solr_doc.get("docOID");
240 Element node = result_doc.createElement(GSXML.DOC_NODE_ELEM);
241 node.setAttribute(GSXML.NODE_ID_ATT, node_id);
242 doc_node_list.appendChild(node);
243
244 System.out.println("\t" + solr_doc.toString());
245 }
246 }
247 } catch (Exception e) {
248 e.printStackTrace();
249 }
250
251 return result;
252
253 }
254
255 protected String getCollectionCoreNamePrefix() {
256 String site_name = this.router.getSiteName();
257 String coll_name = this.cluster_name;
258 String collection_core_name_prefix = site_name + "-" + coll_name;
259 return collection_core_name_prefix;
260 }
261
262}
Note: See TracBrowser for help on using the repository browser.