source: gs3-extensions/solr/trunk/src/perllib/solrserver.pm@ 25889

Last change on this file since 25889 was 25889, checked in by ak19, 12 years ago

Second set of commits for getting activate.pl to deal with solr cores when moving building to index. This time it uses the building- prefix and things still work. However, if the GS3 server is already running, an ant restart is required before searches return results and not sure about whether the incremental case is covered properly. The index reason is still being created for some reason when building.

File size: 11.8 KB
Line 
1###########################################################################
2#
3# solrserver.pm -- class for starting and stopping the Solr/jetty server
4# A component of the Greenstone digital library software
5# from the New Zealand Digital Library Project at the
6# University of Waikato, New Zealand.
7#
8# Copyright (C) 1999 New Zealand Digital Library Project
9#
10# This program is free software; you can redistribute it and/or modify
11# it under the terms of the GNU General Public License as published by
12# the Free Software Foundation; either version 2 of the License, or
13# (at your option) any later version.
14#
15# This program is distributed in the hope that it will be useful,
16# but WITHOUT ANY WARRANTY; without even the implied warranty of
17# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18# GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License
21# along with this program; if not, write to the Free Software
22# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23#
24###########################################################################
25
26
27package solrserver;
28
29use strict;
30#no strict 'refs';
31
32use solrutil;
33
34sub new {
35 my $class = shift(@_);
36 my ($build_dir) = @_;
37
38 my $self = { 'jetty_stop_key' => "greenstone-solr" };
39
40 $self->{'build_dir'} = $build_dir;
41
42 my $search_path = &solrutil::get_search_path();
43
44 my $server_jar = &util::filename_cat("lib","java","solr-jetty-server.jar");
45 my $full_server_jar = solrutil::locate_file($search_path,$server_jar);
46 $self->{'full_server_jar'} = $full_server_jar;
47
48 $self->{'jetty_explicitly_started'} = undef;
49
50 my $jetty_server_port = $ENV{'SOLR_JETTY_PORT'};
51 my $base_url = "http://localhost:$jetty_server_port/solr/";
52 my $admin_url = "http://localhost:$jetty_server_port/solr/admin/cores";
53
54 $self->{'base-url'} = $base_url;
55 $self->{'admin-url'} = $admin_url;
56
57 return bless $self, $class;
58}
59
60
61
62sub _wget_service
63{
64 my $self = shift (@_);
65 my ($output_format,$url,$cgi_get_args) = @_;
66
67 my $full_url = $url;
68
69 $url .= "?$cgi_get_args" if (defined $cgi_get_args);
70
71 my $cmd = "wget -O - \"$url\" 2>&1";
72
73 my $preamble_output = "";
74 my $xml_output = "";
75 my $error_output = undef;
76
77 my $in_preamble = ($output_format eq "xml") ? 1 : 0;
78
79## print STDERR "**** wgetcmd = \n $cmd\n";
80
81 if (open(WIN,"$cmd |")) {
82
83 my $line;
84 while (defined ($line=<WIN>)) {
85
86 if ($line =~ m/ERROR \d+:/) {
87 chomp $line;
88 $error_output = $line;
89 last;
90 }
91 elsif ($line =~ m/failed: Connection refused/) {
92 chomp $line;
93 $error_output = $line;
94 last;
95 }
96 elsif ($in_preamble) {
97 if ($line =~ m/<.*>/) {
98 $in_preamble = 0;
99 }
100 else {
101 $preamble_output .= $line;
102 }
103 }
104
105 if (! $in_preamble) {
106 $xml_output .= $line;
107 }
108 }
109 close(WIN);
110
111 }
112 else {
113 $error_output = "Error: failed to run $cmd\n";
114 $error_output .= " $!\n";
115 }
116
117 my $output = { 'url' => $full_url,
118 'preamble' => $preamble_output,
119 'output' => $xml_output,
120 'error' => $error_output };
121
122 return $output;
123}
124
125
126sub _base_service
127{
128 my $self = shift (@_);
129 my ($cgi_get_args) = @_;
130
131 my $base_url = $self->{'base-url'};
132
133 return $self->_wget_service("html",$base_url,$cgi_get_args);
134}
135
136sub _admin_service
137{
138 my $self = shift (@_);
139 my ($cgi_get_args) = @_;
140
141 my $admin_url = $self->{'admin-url'};
142
143 return $self->_wget_service("xml",$admin_url,$cgi_get_args);
144}
145
146
147sub server_running
148{
149 my $self = shift @_;
150
151 my $output = $self->_base_service();
152
153 my $have_error = defined $output->{'error'};
154
155 my $running = !$have_error;
156
157 return $running;
158}
159
160
161sub admin_ping_core
162{
163 my $self = shift @_;
164 my ($core) = @_;
165
166 my $cgi_get_args = "action=STATUS&core=$core";
167
168 my $ping_status = 1;
169
170 my $output = $self->_admin_service($cgi_get_args);
171
172 if (defined $output->{'error'}) {
173 # severe error, such as failing to connect to the server
174 $ping_status = 0;
175
176 my $url = $output->{'url'};
177 my $preamble = $output->{'preamble'};
178 my $error = $output->{'error'};
179
180 print STDERR "----\n";
181 print STDERR "Error: Failed to get XML response from:\n";
182 print STDERR " $url\n";
183 print STDERR "Output was:\n";
184 print STDERR $preamble if ($preamble ne "");
185 print STDERR "$error\n";
186 print STDERR "----\n";
187 }
188 else {
189
190 # If the collection doesn't exist yet, then there will be
191 # an empty element of the form:
192 # <lst name="collect-doc"/>
193 # where 'collect' is the actual name of the collection,
194 # such as demo
195
196 my $xml_output = $output->{'output'};
197
198 my $empty_element="<lst\\s+name=\"$core\"\\s*\\/>";
199
200 $ping_status = !($xml_output =~ m/$empty_element/s);
201 }
202
203 return $ping_status;
204}
205
206# Some of the Solr CoreAdmin API calls available.
207# See http://wiki.apache.org/solr/CoreAdmin
208sub admin_reload_core
209{
210 my $self = shift @_;
211 my ($core) = @_;
212
213 my $cgi_get_args = "action=RELOAD&core=$core";
214
215 $self->_admin_service($cgi_get_args);
216}
217
218sub admin_rename_core
219{
220 my $self = shift @_;
221 my ($oldcore, $newcore) = @_;
222
223 my $cgi_get_args = "action=RENAME&core=$oldcore&other=$newcore";
224
225 $self->_admin_service($cgi_get_args);
226}
227
228sub admin_swap_core
229{
230 my $self = shift @_;
231 my ($oldcore, $newcore) = @_;
232
233 my $cgi_get_args = "action=SWAP&core=$oldcore&other=$newcore";
234
235 $self->_admin_service($cgi_get_args);
236}
237
238# The ALIAS action is not supported in our version of solr (despite it
239# being marked as experimental in the documentation for Core Admin)
240sub admin_alias_core
241{
242 my $self = shift @_;
243 my ($oldcore, $newcore) = @_;
244
245 my $cgi_get_args = "action=ALIAS&core=$oldcore&other=$newcore";
246
247 $self->_admin_service($cgi_get_args);
248}
249
250sub admin_create_core
251{
252 my $self = shift @_;
253 my ($core, $data_parent_dir) = @_; # data_parent_dir is optional, can be index_dir. Defaults to builddir if not provided
254
255 my ($ds_idx) = ($core =~ m/^.*-(.*?)$/);
256
257 my $cgi_get_args = "action=CREATE&name=$core";
258
259 my $collect_home = $ENV{'GSDLCOLLECTDIR'};
260 my $etc_dirname = &util::filename_cat($collect_home,"etc");
261
262 if(!defined $data_parent_dir) {
263 $data_parent_dir = $self->{'build_dir'};
264 }
265
266 my $idx_dirname = &util::filename_cat($data_parent_dir,$ds_idx); # "dataDir"
267
268 $cgi_get_args .= "&instanceDir=$etc_dirname";
269 $cgi_get_args .= "&dataDir=$idx_dirname";
270
271 $self->_admin_service($cgi_get_args);
272}
273
274# removes (unloads) core from th eext/solr/sorl.xml config file
275sub admin_unload_core
276{
277 my $self = shift @_;
278 my ($core, $delete) = @_;
279
280 my $cgi_get_args = "action=UNLOAD&core=$core"; # &deleteIndex=true from Solr3.3
281 if(defined $delete && $delete == 1) {
282 $cgi_get_args = $cgi_get_args."&deleteIndex=true";
283 }
284
285 $self->_admin_service($cgi_get_args);
286}
287
288sub copy_solrxml_to_web
289{
290 my $self = shift @_;
291
292 my $ext_solrxml = &util::filename_cat($ENV{'GEXT_SOLR'}, "solr.xml");
293 my $web_solrxml = &util::filename_cat($ENV{'GSDL3HOME'}, "ext", "solr", "solr.xml");
294
295 #print STDERR "@@@@ Copying $ext_solrxml to $web_solrxml...\n";
296
297 &util::cp($ext_solrxml, $web_solrxml);
298}
299
300sub start
301{
302 my $self = shift @_;
303
304 my $solr_home = $ENV{'GEXT_SOLR'};
305 my $jetty_stop_port = $ENV{'JETTY_STOP_PORT'};
306 my $jetty_server_port = $ENV{'SOLR_JETTY_PORT'};
307
308 chdir($solr_home);
309
310## my $solr_etc = &util::filename_cat($solr_home,"etc");
311
312 my $server_props = "-DSTOP.PORT=$jetty_stop_port";
313 $server_props .= " -DSTOP.KEY=".$self->{'jetty_stop_key'};
314 $server_props .= " -Dsolr.solr.home=$solr_home";
315
316 my $full_server_jar = $self->{'full_server_jar'};
317
318 my $server_java_cmd = "java $server_props -jar \"$full_server_jar\"";
319
320
321 my $server_status = "unknown";
322
323 if ($self->server_running()) {
324 $server_status = "already-running";
325 }
326 elsif (open(STARTIN,"$server_java_cmd 2>&1 |")) {
327
328## print STDERR "**** startup up server with cmd start =\n $server_java_cmd\n";
329
330 my $line;
331 while (defined($line=<STARTIN>)) {
332 # Scan through output until you see a line like:
333 # 2011-08-22 .. :INFO::Started [email protected]:8983
334 # which signifies that the server has started up and is
335 # "ready and listening"
336
337 if (($line =~ m/^(WARN|ERROR|SEVERE):/)
338 || ($line =~ m/^[0-9 :-]*(WARN|ERROR|SEVERE)::/)) {
339 print "Jetty startup: $line";
340 }
341
342 if ($line =~ m/WARN::failed SocketConnector/) {
343 if ($line =~ m/Address already in use/) {
344 $server_status = "already-running";
345 }
346 else {
347 $server_status = "failed-to-start";
348 }
349 last;
350 }
351
352 if ($line =~ m/INFO::Started SocketConnector/) {
353 $server_status = "explicitly-started";
354 last;
355 }
356 }
357 }
358 else {
359 print STDERR "Error: failed to start solr-jetty-server\n";
360 print STDERR "$!\n";
361 print STDERR "Command attempted was:\n";
362 print STDERR " $server_java_cmd\n";
363 print STDERR "run from directory:\n";
364 print STDERR " $solr_home\n";
365 print STDERR "----\n";
366
367 exit -1;
368 }
369
370 if ($server_status eq "explicitly-started") {
371 $self->{'jetty_explicitly_started'} = 1;
372 print "Jetty server ready and listening for connections on port";
373 print " $jetty_server_port\n";
374
375 # now we know the server is ready to accept connections, fork a
376 # child process that continues to listen to the output and
377 # prints out any lines that are not INFO lines
378
379 if (fork()==0) {
380 # child process
381
382 my $line;
383 while (defined ($line = <STARTIN>)) {
384
385# if (($line =~ m/^(WARN|ERROR|SEVERE):/)
386# || ($line =~ m/^[0-9 :-]*(WARN|ERROR|SEVERE)::/)) {
387# print "Jetty $line";
388# }
389
390 # skip info lines
391 next if ($line =~ m/^INFO:/);
392 next if ($line =~ m/^[0-9 :-]*INFO::/);
393 next if ($line =~ m/^\d{2}\/\d{2}\/\d{4}\s+/);
394 next if ($line =~ m/^\d{4}-\d{2}-\d{2}\s+/);
395
396## next if ($line =~ m/^\s*\w+{.*}/);
397
398 # if here, then some non-trival message has been logged
399 print "Jetty/Solr processing: $line";
400 }
401 close(STARTIN);
402
403 # And now stop nicely
404 exit 0;
405 }
406 # otherwise let the parent continue on
407 }
408 elsif ($server_status eq "already-running") {
409 print STDERR "Using existing server detected on port $jetty_server_port\n";
410 $self->{'jetty_explicitly_started'} = 0;
411 }
412 elsif ($server_status eq "failed-to-start") {
413 print STDERR "Started Solr/Jetty web server on port $jetty_server_port";
414 print STDERR ", but encountered an initialization error\n";
415 exit -1;
416 }
417
418}
419
420sub explicitly_started
421{
422 my $self = shift @_;
423
424 return $self->{'jetty_explicitly_started'};
425}
426
427sub stop
428{
429 my $self = shift @_;
430 my ($options) = @_;
431
432 my $solr_home = $ENV{'GEXT_SOLR'};
433
434 chdir($solr_home);
435
436 # defaults
437 my $do_wait = 1;
438 my $output_verbosity = 1;
439
440 if (defined $options) {
441 if (defined $options->{'do_wait'}) {
442 $do_wait = $options->{'do_wait'};
443 }
444 if (defined $options->{'output_verbosity'}) {
445 $output_verbosity = $options->{'output_verbosity'};
446 }
447 }
448
449 my $full_server_jar = $self->{'full_server_jar'};
450 my $jetty_stop_port = $ENV{'JETTY_STOP_PORT'};
451
452 my $server_props = "-DSTOP.PORT=$jetty_stop_port";
453 $server_props .= " -DSTOP.KEY=".$self->{'jetty_stop_key'};
454 my $server_java_cmd = "java $server_props -jar \"$full_server_jar\" --stop";
455
456## print STDERR "**** java server stop cmd:\n $server_java_cmd\n";
457
458 if (open(STOPIN,"$server_java_cmd 2>&1 |")) {
459
460 my $line;
461 while (defined($line=<STOPIN>)) {
462 print "Jetty shutdown: $line" if ($output_verbosity>1);
463 }
464 close(STOPIN);
465
466 if ($do_wait) {
467 wait(); # let the child process finish
468 }
469
470 if ($output_verbosity>0) {
471 print "Jetty server shutdown\n";
472 }
473 }
474 else {
475 print STDERR "Error: failed to stop solr-jetty-server\n";
476 print STDERR "$!\n";
477 print STDERR "Command attempted was:\n";
478 print STDERR " $server_java_cmd\n";
479 print STDERR "run from directory:\n";
480 print STDERR " $solr_home\n";
481 print STDERR "----\n";
482
483 exit -2;
484 }
485}
486
487
488
4891;
Note: See TracBrowser for help on using the repository browser.