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

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

First working version of activate.pl modified for handling solr collections. It needs to update solr cores when moving building to index.

File size: 11.7 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) = @_;
279
280 my $cgi_get_args = "action=UNLOAD&core=$core"; # &deleteIndex=true from Solr3.3
281
282 $self->_admin_service($cgi_get_args);
283}
284
285sub copy_solrxml_to_web
286{
287 my $self = shift @_;
288
289 my $ext_solrxml = &util::filename_cat($ENV{'GEXT_SOLR'}, "solr.xml");
290 my $web_solrxml = &util::filename_cat($ENV{'GSDL3HOME'}, "ext", "solr", "solr.xml");
291
292 #print STDERR "@@@@ Copying $ext_solrxml to $web_solrxml...\n";
293
294 &util::cp($ext_solrxml, $web_solrxml);
295}
296
297sub start
298{
299 my $self = shift @_;
300
301 my $solr_home = $ENV{'GEXT_SOLR'};
302 my $jetty_stop_port = $ENV{'JETTY_STOP_PORT'};
303 my $jetty_server_port = $ENV{'SOLR_JETTY_PORT'};
304
305 chdir($solr_home);
306
307## my $solr_etc = &util::filename_cat($solr_home,"etc");
308
309 my $server_props = "-DSTOP.PORT=$jetty_stop_port";
310 $server_props .= " -DSTOP.KEY=".$self->{'jetty_stop_key'};
311 $server_props .= " -Dsolr.solr.home=$solr_home";
312
313 my $full_server_jar = $self->{'full_server_jar'};
314
315 my $server_java_cmd = "java $server_props -jar \"$full_server_jar\"";
316
317
318 my $server_status = "unknown";
319
320 if ($self->server_running()) {
321 $server_status = "already-running";
322 }
323 elsif (open(STARTIN,"$server_java_cmd 2>&1 |")) {
324
325## print STDERR "**** startup up server with cmd start =\n $server_java_cmd\n";
326
327 my $line;
328 while (defined($line=<STARTIN>)) {
329 # Scan through output until you see a line like:
330 # 2011-08-22 .. :INFO::Started [email protected]:8983
331 # which signifies that the server has started up and is
332 # "ready and listening"
333
334 if (($line =~ m/^(WARN|ERROR|SEVERE):/)
335 || ($line =~ m/^[0-9 :-]*(WARN|ERROR|SEVERE)::/)) {
336 print "Jetty startup: $line";
337 }
338
339 if ($line =~ m/WARN::failed SocketConnector/) {
340 if ($line =~ m/Address already in use/) {
341 $server_status = "already-running";
342 }
343 else {
344 $server_status = "failed-to-start";
345 }
346 last;
347 }
348
349 if ($line =~ m/INFO::Started SocketConnector/) {
350 $server_status = "explicitly-started";
351 last;
352 }
353 }
354 }
355 else {
356 print STDERR "Error: failed to start solr-jetty-server\n";
357 print STDERR "$!\n";
358 print STDERR "Command attempted was:\n";
359 print STDERR " $server_java_cmd\n";
360 print STDERR "run from directory:\n";
361 print STDERR " $solr_home\n";
362 print STDERR "----\n";
363
364 exit -1;
365 }
366
367 if ($server_status eq "explicitly-started") {
368 $self->{'jetty_explicitly_started'} = 1;
369 print "Jetty server ready and listening for connections on port";
370 print " $jetty_server_port\n";
371
372 # now we know the server is ready to accept connections, fork a
373 # child process that continues to listen to the output and
374 # prints out any lines that are not INFO lines
375
376 if (fork()==0) {
377 # child process
378
379 my $line;
380 while (defined ($line = <STARTIN>)) {
381
382# if (($line =~ m/^(WARN|ERROR|SEVERE):/)
383# || ($line =~ m/^[0-9 :-]*(WARN|ERROR|SEVERE)::/)) {
384# print "Jetty $line";
385# }
386
387 # skip info lines
388 next if ($line =~ m/^INFO:/);
389 next if ($line =~ m/^[0-9 :-]*INFO::/);
390 next if ($line =~ m/^\d{2}\/\d{2}\/\d{4}\s+/);
391 next if ($line =~ m/^\d{4}-\d{2}-\d{2}\s+/);
392
393## next if ($line =~ m/^\s*\w+{.*}/);
394
395 # if here, then some non-trival message has been logged
396 print "Jetty/Solr processing: $line";
397 }
398 close(STARTIN);
399
400 # And now stop nicely
401 exit 0;
402 }
403 # otherwise let the parent continue on
404 }
405 elsif ($server_status eq "already-running") {
406 print STDERR "Using existing server detected on port $jetty_server_port\n";
407 $self->{'jetty_explicitly_started'} = 0;
408 }
409 elsif ($server_status eq "failed-to-start") {
410 print STDERR "Started Solr/Jetty web server on port $jetty_server_port";
411 print STDERR ", but encountered an initialization error\n";
412 exit -1;
413 }
414
415}
416
417sub explicitly_started
418{
419 my $self = shift @_;
420
421 return $self->{'jetty_explicitly_started'};
422}
423
424sub stop
425{
426 my $self = shift @_;
427 my ($options) = @_;
428
429 my $solr_home = $ENV{'GEXT_SOLR'};
430
431 chdir($solr_home);
432
433 # defaults
434 my $do_wait = 1;
435 my $output_verbosity = 1;
436
437 if (defined $options) {
438 if (defined $options->{'do_wait'}) {
439 $do_wait = $options->{'do_wait'};
440 }
441 if (defined $options->{'output_verbosity'}) {
442 $output_verbosity = $options->{'output_verbosity'};
443 }
444 }
445
446 my $full_server_jar = $self->{'full_server_jar'};
447 my $jetty_stop_port = $ENV{'JETTY_STOP_PORT'};
448
449 my $server_props = "-DSTOP.PORT=$jetty_stop_port";
450 $server_props .= " -DSTOP.KEY=".$self->{'jetty_stop_key'};
451 my $server_java_cmd = "java $server_props -jar \"$full_server_jar\" --stop";
452
453## print STDERR "**** java server stop cmd:\n $server_java_cmd\n";
454
455 if (open(STOPIN,"$server_java_cmd 2>&1 |")) {
456
457 my $line;
458 while (defined($line=<STOPIN>)) {
459 print "Jetty shutdown: $line" if ($output_verbosity>1);
460 }
461 close(STOPIN);
462
463 if ($do_wait) {
464 wait(); # let the child process finish
465 }
466
467 if ($output_verbosity>0) {
468 print "Jetty server shutdown\n";
469 }
470 }
471 else {
472 print STDERR "Error: failed to stop solr-jetty-server\n";
473 print STDERR "$!\n";
474 print STDERR "Command attempted was:\n";
475 print STDERR " $server_java_cmd\n";
476 print STDERR "run from directory:\n";
477 print STDERR " $solr_home\n";
478 print STDERR "----\n";
479
480 exit -2;
481 }
482}
483
484
485
4861;
Note: See TracBrowser for help on using the repository browser.