source: main/trunk/greenstone2/perllib/servercontrol.pm@ 31507

Last change on this file since 31507 was 31507, checked in by ak19, 7 years ago

BUGFIX to servercontrol.pm. servercontrol::config() was merging stderr and stdout of wget command in order to work out response code, response message (both going to stderr) and html page's text string (goes to stdout) in order to parse the ping response. This worked fine all the times I'd tested it before, such as some months back when I tested the incremental build tutorial. But the merge of stderr and stdout failed today and showed how bad the idea to merge the two was: the very line in the HTML string from STDOUT that was being parsed and compared against an expected value, was interspersed with output from stderr. So the regex didn't match and ultimately the collection was assumed deactivated when activated and vice-versa. Two fixes attempted and committing the fix that worked: the wgeet command stores the downloaded HTML to a file named by timestamp and deleted as soon as read. The failed attempt was to use open3, but there were warnings in the perl online manual about the dangers blocking when attempting to read from stderr and stdout streams, and I'm not sure if this is what I encountered, but I decided against it and returned to using the successful file version of the fix.

File size: 28.4 KB
Line 
1#############################################################################
2#
3# activate.pm -- functions to get the GS library URL, ping the library URL,
4# activate and deactivate a collection.
5#
6# A component of the Greenstone digital library software
7# from the New Zealand Digital Library Project at the
8# University of Waikato, New Zealand.
9#
10# Copyright (C) 1999 New Zealand Digital Library Project
11#
12# This program is free software; you can redistribute it and/or modify
13# it under the terms of the GNU General Public License as published by
14# the Free Software Foundation; either version 2 of the License, or
15# (at your option) any later version.
16#
17# This program is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU General Public License for more details.
21#
22# You should have received a copy of the GNU General Public License
23# along with this program; if not, write to the Free Software
24# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25#
26###############################################################################
27
28package servercontrol;
29
30
31use strict;
32no strict 'refs'; # allow filehandles to be variables and vice versa
33no strict 'subs'; # allow barewords (eg STDERR) as function arguments
34
35# Greenstone includes
36use printusage;
37use parse2;
38
39
40# The perl library imports below are used by deprecated methods config_old(), is_URL_active() and pingHost()
41# If the following library imports are not supported by your perl installation, comment out these
42# imports and move the methods config_old(), is_URL_active() and pingHost() out to a temporary file.
43use HTTP::Response;
44use LWP::Simple qw($ua !head); # import useragent object as $ua from the full LWP to use along with LWP::Simple
45 # don't import LWP::Simple's head function by name since it can conflict with CGI:head())
46#use CGI qw(:standard); # then only CGI.pm defines a head()
47use Net::Ping;
48use URI;
49
50
51sub new
52{
53 my $class = shift(@_);
54
55 my ($qualified_collection, $site, $verbosity, $build_dir, $index_dir, $collect_dir, $library_url, $library_name) = @_;
56
57 # library_url: to be specified on the cmdline if not using a GS-included web server
58 # the GSDL_LIBRARY_URL env var is useful when running cmdline buildcol.pl in the linux package manager versions of GS3
59
60 my $self = {'build_dir' => $build_dir,
61 'index_dir' => $index_dir,
62 'collect_dir' => $collect_dir,
63 'site' => $site,
64 'qualified_collection' => $qualified_collection,
65 #'is_persistent_server' => undef,
66 'library_url' => $library_url || $ENV{'GSDL_LIBRARY_URL'} || undef, # to be specified on the cmdline if not using a GS-included web server
67 'library_name' => $library_name,
68 #'gs_mode' => "gs2",
69 'verbosity' => $verbosity || 2
70 };
71
72 if ((defined $site) && ($site ne "")) { # GS3
73 $self->{'gs_mode'} = "gs3";
74 } else {
75 $self->{'gs_mode'} = "gs2";
76 }
77
78 return bless($self, $class);
79}
80
81## TODO: gsprintf to $self->{'out'} in these 2 print functions
82## See buildcolutils.pm new() for setting up $out
83
84sub print_task_msg {
85 my $self = shift(@_);
86 my ($task_msg, $verbosity_setting) = @_;
87
88 $verbosity_setting = $self->{'verbosity'} unless $verbosity_setting;
89 #$verbosity_setting = 1 unless defined $verbosity;
90 if($verbosity_setting >= 1) {
91 print STDERR "\n";
92 print STDERR "************************\n";
93 print STDERR "* $task_msg\n";
94 print STDERR "************************\n";
95 }
96}
97
98# Prints messages if the verbosity is right. Does not add new lines.
99sub print_msg {
100 my $self = shift(@_);
101 my ($msg, $min_verbosity, $verbosity_setting) = @_;
102
103 # only display error messages if the current
104 # verbosity setting >= the minimum verbosity level
105 # needed for that message to be displayed.
106
107 $verbosity_setting = $self->{'verbosity'} unless defined $verbosity_setting;
108 $min_verbosity = 1 unless defined $min_verbosity;
109 if($verbosity_setting >= $min_verbosity) { # by default display all 1 messages
110 print STDERR "$msg";
111 }
112}
113
114# Method to send a command to a GS2 or GS3 library_URL
115# the commands used in this script can be activate, deactivate, ping,
116# and is-persistent (is-persistent only implemented for GS2).
117sub config {
118 my $self = shift(@_);
119 my ($command, $check_message_against_regex, $expected_error_code, $silent) = @_;
120
121 my $library_url = $self->get_library_URL(); #$self->{'library_url'};
122
123
124 # Gatherer.java's configGS3Server doesn't use the site variable
125 # so we don't have to either
126
127 # for GS2, getting the HTTP status isn't enough, we need to read the output
128 # since this is what CollectionManager.config() stipulates.
129 # Using LWP::UserAgent::get($url) for this
130
131 if(!defined $library_url) {
132 return 0;
133 }
134 else {
135 # ampersands need to be escaped
136 # - with single quotes around it for linux for the cmd to run in bash subshell
137 # - with a ^ before it on windows for the cmd to run in a DOS prompt subshell
138 # - or the entire wget command should be nested in double quotes (single quotes don't work on windows)
139 my $wgetCommand = $command;
140
141 my $wget_file_path = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'}, "bin", $ENV{'GSDLOS'}, "wget");
142 my $tmpfilename = time . ".html"; # random name for file wherein we'll store the HTML page retrieved by wget
143
144 # https://www.gnu.org/software/wget/manual/wget.html
145 # output-document set to - (STDOUT), so page is streamed to STDOUT
146 # timeout: 5 seconds, tries: 1
147 # wget sends status information and response code to STDERR, so redirect it to STDOUT
148 # Searching for "perl backtick operator redirect stderr to stdout":
149 # http://www.perlmonks.org/?node=How%20can%20I%20capture%20STDERR%20from%20an%20external%20command%3F
150 ##$wgetCommand = "\"$wget_file_path\" --spider -T 5 -t 1 \"$library_url$wgetCommand\" 2>&1"; # won't save page
151 #$wgetCommand = "\"$wget_file_path\" --output-document=- -T 5 -t 1 \"$library_url$wgetCommand\" 2>&1"; # THIS CAN MIX UP STDERR WITH STDOUT IN THE VERY LINE WE REGEX TEST AGAINST EXPECTED OUTPUT!!
152 $wgetCommand = "\"$wget_file_path\" --output-document=$tmpfilename -T 5 -t 1 \"$library_url$wgetCommand\" 2>&1"; # keep stderr (response code, response_content) separate from html page content
153
154 ##print STDERR "@@@@ $wgetCommand\n";
155
156 my $response_content = `$wgetCommand`;
157 my $response_code = undef;
158 my @lines = split( /\n/, $response_content );
159 foreach my $line (@lines) {
160 #print STDERR "@@@@ LINE: $line\n";
161 if($line =~ m@failed: Connection timed out.$@) { # linux
162 $response_code = "failed: Connection timed out.";
163 last; # break keyword in perl = last
164 }
165 elsif($line =~ m@Giving up.$@) { # windows (unless -T 5 -t 1 is not passed in)
166 $response_code = "failed: Giving up.";
167 last; # break keyword in perl = last
168 }
169 elsif($line =~ m@failed: Connection refused.$@) {
170 $response_code = "failed: Connection refused.";
171 last; # break keyword in perl = last
172 }
173 elsif($line =~ m@HTTP request sent, @) {
174 $response_code = $line;
175 $response_code =~ s@[^\d]*(.*)$@$1@;
176 last;
177 }
178 }
179
180 if($command =~ m@ping@ && $response_code =~ m@failed: (Connection refused|Giving up)@) {
181 # server not running
182 $self->print_msg("*** Server not running. $library_url$command\n", 3);
183 return 0;
184 }
185 if($response_code && $response_code eq "200 OK") {
186 $self->print_msg("*** Command $library_url$command\n", 3);
187 $self->print_msg("*** HTTP Response Status: $response_code - Complete.", 3);
188
189 # check the page content is as expected
190 #my $resultstr = $response_content;
191
192 open(FIN,"<$tmpfilename") or die "servercontrol.pm: Unable to open $tmpfilename to read ping response page...ERROR: $!\n";
193 my $resultstr;
194 # Read in the entire contents of the file in one hit
195 sysread(FIN, $resultstr, -s FIN);
196 close(FIN);
197 &FileUtils::removeFiles("$tmpfilename");
198
199 #$resultstr =~ s@.*gs_content\"\>@@s; ## only true for default library servlet
200 #$resultstr =~ s@</div>.*@@s;
201 if($resultstr =~ m/$check_message_against_regex/) {
202 $self->print_msg(" Response as expected.\n", 3);
203 $self->print_msg("@@@@@@ Got result:\n$resultstr\n", 4);
204 return 1;
205 } else {
206 # if we expect the collection to be inactive, then we'd be in silent mode: if so,
207 # don't print out the "ping did not succeed" response, but print out any other messages
208
209 # So we only suppress the ping col "did not succeed" response if we're in silent mode
210 # But if any message other than ping "did not succeed" is returned, we always print it
211 if($resultstr !~ m/did not succeed/ || !$silent) {
212 $self->print_msg("\n\tBUT: command $library_url$command response UNEXPECTED.\n", 3);
213 $self->print_msg("*** Got message:\n$response_content.\n", 4);
214 $self->print_msg("*** Got result:\n$resultstr\n", 3);
215 }
216 return 0; # ping on a collection may "not succeed."
217 }
218 }
219 elsif($response_code && $response_code =~ m@^(4|5)\d\d@) { # client side errors start with 4xx, server side with 5xx
220 # check the page content is as expected
221 if(defined $expected_error_code && $response_code =~ m@^$expected_error_code@) {
222 $self->print_msg(" Response status $response_code as expected.\n", 3);
223 } else {
224 $self->print_msg("*** Command $library_url$command\n");
225 $self->print_msg("*** Unexpected error type 1. HTTP Response Status: $response_code - Failed.\n");
226 }
227 return 0; # return false, since the response_code was an error, expected or not
228 }
229 else { # also if response_code is still undefined, as can happen with connection timing out
230 $self->print_msg("*** Command $library_url$command\n");
231 if(defined $response_code) {
232 $self->print_msg("*** Unexpected error type 2. HTTP Response Status: $response_code - Failed.\n");
233 } else {
234 $self->print_msg("*** Unexpected error type 3. Failed:\n\n$response_content\n\n");
235 }
236 return 0;
237 }
238 #print STDERR "********** WgetCommand: $wgetCommand\n\n";
239 #print STDERR "********** Response_content:\n$response_content\n\n";
240 #print STDERR "********** Response_CODE: $response_code\n";
241
242 }
243}
244
245sub deactivate_collection {
246 my $self = shift(@_);
247
248 my $gs_mode = $self->{'gs_mode'};
249 my $qualified_collection = $self->{'qualified_collection'};
250
251 if($gs_mode eq "gs2") {
252 my $DEACTIVATE_COMMAND = "?a=config&cmd=release-collection&c=";
253 my $check_message_against_regex = q/configured release-collection/;
254 $self->config($DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
255 }
256 elsif ($gs_mode eq "gs3") {
257 my $DEACTIVATE_COMMAND = "?a=s&sa=d&st=collection&sn=";
258 my $check_message_against_regex = "collection: $qualified_collection deactivated";
259 $self->config($DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
260 }
261}
262
263sub activate_collection {
264 my $self = shift(@_);
265
266 my $gs_mode = $self->{'gs_mode'};
267 my $qualified_collection = $self->{'qualified_collection'};
268
269 if($gs_mode eq "gs2") {
270 my $ACTIVATE_COMMAND = "?a=config&cmd=add-collection&c=";
271 my $check_message_against_regex = q/configured add-collection/;
272 $self->config($ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
273 }
274 elsif ($gs_mode eq "gs3") {
275 my $ACTIVATE_COMMAND = "?a=s&sa=a&st=collection&sn=";
276 my $check_message_against_regex = "collection: $qualified_collection activated";
277 $self->config($ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
278 }
279}
280
281sub ping {
282 my $self = shift(@_);
283 my $command = shift(@_);
284 my $silent = shift(@_);
285
286 # If the GS server is not running, we *expect* to see a "500" status code.
287 # If the GS server is running, then "Ping" ... "succeeded" is expected on success.
288 # When pinging an inactive collection, it will say it did "not succeed". This is
289 # a message of interest to return.
290 my $check_responsemsg_against_regex = q/(succeeded)/;
291 my $expected_error_code = 500;
292
293 $self->print_msg("*** COMMAND WAS: |$command| ***\n", 4);
294
295 return $self->config($command, $check_responsemsg_against_regex, $expected_error_code, $silent);
296}
297
298# send a pingaction to the GS library. General server-level ping.
299sub ping_library {
300 my $self = shift(@_);
301
302 my $gs_mode = $self->{'gs_mode'};
303
304 my $command = "";
305 if($gs_mode eq "gs2") {
306 $command = "?a=ping";
307 }
308 elsif ($gs_mode eq "gs3") {
309 $command = "?a=s&sa=ping";
310 }
311 return $self->ping($command);
312}
313
314
315# send a pingaction to a collection in GS library to check if it's active
316sub ping_library_collection {
317 my $self = shift(@_);
318 my $silent = shift(@_);
319
320 my $gs_mode = $self->{'gs_mode'};
321 my $qualified_collection = $self->{'qualified_collection'};
322
323 my $command = "";
324 if($gs_mode eq "gs2") {
325 $command = "?a=ping&c=$qualified_collection";
326 }
327 elsif ($gs_mode eq "gs3") {
328 $command = "?a=s&sa=ping&st=collection&sn=$qualified_collection";
329 }
330 return $self->ping($command, $silent);
331}
332
333# return true if server is persistent, by calling is-persistent on library_url
334# this is only for GS2, since the GS3 server is always persistent
335sub is_persistent {
336 my $self = shift(@_);
337
338 if($self->{'gs_mode'} eq "gs3") { # GS3 server is always persistent
339 return 1;
340 }
341
342 my $command = "?a=is-persistent";
343 my $check_responsemsg_against_regex = q/true/; # isPersistent: true versus isPersistent: false
344 return $self->config($command, $check_responsemsg_against_regex);
345}
346
347sub set_library_URL {
348 my $self = shift(@_);
349 my $library_url = shift(@_);
350 $self->{'library_url'} = $library_url;
351}
352
353sub get_library_URL {
354 my $self = shift(@_);
355
356 # For web servers that are external to a Greenstone installation,
357 # the user can pass in their web server's library URL.
358 if($self->{'library_url'}) {
359 return $self->{'library_url'};
360 }
361
362 # For web servers included with GS (like tomcat for GS3 and server.exe
363 # and apache for GS2), we work out the library URL:
364 my ($gs_mode, $lib_name); # gs_mode can be gs3 or gs2, lib_name is the custom servlet name
365 $gs_mode = $self->{'gs_mode'};
366 $lib_name = $self->{'library_name'};
367
368 # If we get here, we are dealing with a server included with GS.
369 # For GS3, we ask ant for the library URL.
370 # For GS2, we derive the URL from the llssite.cfg file.
371
372 my $url = undef;
373
374 if($gs_mode eq "gs2") {
375 my $llssite_cfg = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'}, "llssite.cfg");
376
377 if(-f $llssite_cfg) {
378 # check llssite.cfg for line with url property
379 # for server.exe also need to use portnumber and enterlib properties
380
381 # Read in the entire contents of the file in one hit
382 if (!open (FIN, $llssite_cfg)) {
383 $self->print_msg("activate.pl::get_library_URL failed to open $llssite_cfg ($!)\n");
384 return undef;
385 }
386
387 my $contents;
388 sysread(FIN, $contents, -s FIN);
389 close(FIN);
390
391 my @lines = split(/[\n\r]+/, $contents); # split on carriage-returns and/or linefeeds
392 my $enterlib = "";
393 my $portnumber = "8282"; # will remain empty (implicit port 80) unless it's specifically been assigned
394
395 foreach my $line (@lines) {
396 if($line =~ m/^url=(.*)$/) {
397 $url = $1;
398 } elsif($line =~ m/^enterlib=(.*)$/) {
399 $enterlib = $1;
400 } elsif($line =~ m/^portnumber=(.*)$/) {
401 $portnumber = $1;
402 }
403 }
404
405 if(!$url) {
406 return undef;
407 }
408 elsif($url eq "URL_pending") { # library is not running
409 # do not process url=URL_pending in the file, since for server.exe
410 # this just means the Enter Library button hasn't been pressed yet
411 $url = undef;
412 }
413 else {
414 # In the case of server.exe, need to do extra work to get the proper URL
415 # But first, need to know whether we're indeed dealing with server.exe:
416
417 # compare the URL's domain to the full URL
418 # E.g. for http://localhost:8383/greenstone3/cgi-bin, the domain is localhost:8383
419 my $uri = URI->new( $url );
420 my $host = $uri->host;
421 #print STDERR "@@@@@ host: $host\n";
422 if($url =~ m/https?:\/\/$host(\/)?$/) {
423 #if($url !~ m/https?:\/\/$host:$portnumber(\/)?/ || $url =~ m/https?:\/\/$host(\/)?$/) {
424 # (if the URL does not contain the portnumber, OR if the port is implicitly 80 and)
425 # If the domain with http:// prefix is completely the same as the URL, assume server.exe
426 # then the actual URL is the result of suffixing the port and enterlib properties in llssite.cfg
427 $url = $url.":".$portnumber.$enterlib;
428 } # else, apache web server
429
430 }
431 }
432 } elsif($gs_mode eq "gs3") {
433 # Either check build.properties for tomcat.server, tomcat.port and app.name (and default servlet name).
434 # app.name is stored in app.path by build.xml. Need to move app.name in build.properties from build.xml
435
436 # Or, run the new target get-default-servlet-url
437 # the output can look like:
438 #
439 # Buildfile: build.xml
440 # [echo] os.name: Windows Vista
441 #
442 # get-default-servlet-url:
443 # [echo] http://localhost:8383/greenstone3/library
444 # BUILD SUCCESSFUL
445 # Total time: 0 seconds
446
447 #my $output = qx/ant get-default-servlet-url/; # backtick operator, to get STDOUT (else 2>&1)
448 # see http://stackoverflow.com/questions/799968/whats-the-difference-between-perls-backticks-system-and-exec
449
450 # The get-default-servlet-url ant target can be run from anywhere by specifying the
451 # location of GS3's ant build.xml buildfile. Activate.pl can be run from anywhere for GS3
452 # GSDL3SRCHOME will be set for GS3 by gs3-setup.sh, a step that would have been necessary
453 # to run the activate.pl script in the first place
454 my $perl_command = "ant -buildfile \"$ENV{'GSDL3SRCHOME'}/build.xml\" get-default-servlet-url";
455
456 if (open(PIN, "$perl_command |")) {
457 while (defined (my $perl_output_line = <PIN>)) {
458 if($perl_output_line =~ m@(https?):\/\/(\S*)@) { # grab all the non-whitespace chars
459 $url="$1://".$2; # preserve the http protocol #$url="http://".$1;
460 }
461 }
462 close(PIN);
463 } else {
464 $self->print_msg("activate.pl::get_library_URL: Failed to run $perl_command to work out library URL for $gs_mode\n");
465 }
466 if(defined $lib_name) {
467 # replace the servlet_name portion of the url found, with the given library_name
468 $url =~ s@/[^/]*$@/$lib_name@;
469 }
470 }
471
472 # either the url is still undef or it is now set
473 #print STDERR "\n@@@@@ final URL:|$url|\n" if $url;
474 #print STDERR "\n@@@@@ URL still undef\n" if !$url;
475
476 $self->{'library_url'} = $url;
477 return $url;
478}
479
480
481sub do_deactivate {
482 my $self = shift(@_);
483
484 # 1. Get library URL
485
486 # For web servers that are external to a Greenstone installation,
487 # the user can pass in their web server's library URL.
488 # For web servers included with GS (like tomcat for GS3 and server.exe
489 # and apache for GS2), we work out the library URL:
490
491 # Can't do $self->{'library_url'}, because it may not yet be set
492 my $library_url = $self->get_library_URL(); # returns undef if no valid server URL
493
494 if(!defined $library_url) { # undef if no valid server URL
495 return; # can't do any deactivation without a valid server URL
496 }
497
498 my $is_persistent_server = $self->{'is_persistent_server'};
499 my $qualified_collection = $self->{'qualified_collection'};
500
501 # CollectionManager's installCollection phase in GLI
502 # 2. Ping the library URL, and if it's a persistent server and running, release the collection
503
504 $self->print_msg("Pinging $library_url\n");
505 if ($self->ping_library()) { # server running
506
507 # server is running, so release the collection if
508 # the server is persistent and the collection is active
509
510 # don't need to work out persistency of server more than once, since the libraryURL hasn't changed
511 if (!defined $is_persistent_server) {
512 $self->print_msg("Checking if Greenstone server is persistent\n");
513 $is_persistent_server = $self->is_persistent();
514 $self->{'is_persistent_server'} = $is_persistent_server;
515 }
516
517 if ($is_persistent_server) { # only makes sense to issue activate and deactivate cmds to a persistent server
518
519 $self->print_msg("Checking if the collection $qualified_collection is already active\n");
520 my $collection_active = $self->ping_library_collection();
521
522 if ($collection_active) {
523 $self->print_msg("De-activating collection $qualified_collection\n");
524 $self->deactivate_collection();
525 }
526 else {
527 $self->print_msg("Collection is not active => No need to deactivate\n");
528 }
529 }
530 else {
531 $self->print_msg("Server is not persistent => No need to deactivate collection\n");
532 }
533 }
534 else {
535 $self->print_msg("No response to Ping => Taken to mean server is not running\n");
536 }
537
538 return $is_persistent_server;
539}
540
541sub do_activate {
542 my $self = shift @_;
543
544 my $library_url = $self->get_library_URL(); # Can't do $self->{'library_url'}; as it may not be set yet
545
546 if(!defined $library_url) { # undef if no valid server URL
547 return; # nothing to activate if without valid server URL
548 }
549
550 my $is_persistent_server = $self->{'is_persistent_server'};
551 my $qualified_collection = $self->{'qualified_collection'};
552
553 $self->print_msg("Pinging $library_url\n");
554 if ($self->ping_library()) { # server running
555
556 # don't need to work out persistency of server more than once, since the libraryURL hasn't changed
557 if (!defined $is_persistent_server) {
558 $self->print_msg("Checking if Greenstone server is persistent\n");
559 $is_persistent_server = $self->is_persistent();
560 $self->{'is_persistent_server'} = $is_persistent_server;
561 }
562
563 if ($is_persistent_server) { # persistent server, so can try activating collection
564
565 $self->print_msg("Checking if the collection $qualified_collection is not already active\n");
566
567 # Since we could have deactivated the collection at this point,
568 # it is likely that it is not yet active. When pinging the collection
569 # a "ping did not succeed" message is expected, therefore tell the ping
570 # to proceed silently
571 my $silent = 1;
572 my $collection_active = $self->ping_library_collection($silent);
573
574 if (!$collection_active) {
575 $self->print_msg(" Collection is not active.\n");
576 $self->print_msg("Activating collection $qualified_collection\n");
577 $self->activate_collection();
578
579 # unless an error occurred, the collection should now be active:
580 $collection_active = $self->ping_library_collection(); # not silent if ping did not succeed
581 if(!$collection_active) {
582 $self->print_msg("ERROR: collection $qualified_collection did not get activated\n");
583 }
584 }
585 else {
586 $self->print_msg("Collection is already active => No need to activate\n");
587 }
588 }
589 else {
590 $self->print_msg("Server is not persistent => No need to activate collection\n");
591 }
592 }
593 else {
594 $self->print_msg("No response to Ping => Taken to mean server is not running\n");
595 }
596
597 return $is_persistent_server;
598}
599
600
601#########################################################
602### UNUSED METHODS - CAN BE HANDY
603
604
605# This method uses the perl libraries we're advised to use in place of wget for pinging and retrieving web
606# pages. The problem is that not all perl installations may support these libraries. So we now use the new
607# config() method further above, which uses the wget included in Greenstone binary installations.
608# If the library imports at page top conflict, comment out those imports and move the methods config_old(),
609# is_URL_active() and pingHost() out to a temporary file.
610#
611# If for some reason you can't use wget, then rename the config() method to config_old(), and rename the
612# method below to config() and things should work as before.
613sub config_old {
614 my $self = shift(@_);
615 my ($command, $check_message_against_regex, $expected_error_code, $silent) = @_;
616
617 my $library_url = $self->get_library_URL(); #$self->{'library_url'};
618
619
620 # Gatherer.java's configGS3Server doesn't use the site variable
621 # so we don't have to either
622
623 # for GS2, getting the HTTP status isn't enough, we need to read the output
624 # since this is what CollectionManager.config() stipulates.
625 # Using LWP::UserAgent::get($url) for this
626
627 if(!defined $library_url) {
628 return 0;
629 }
630 else {
631 $ua->timeout(5); # set LWP useragent to 5s max timeout for testing the URL
632 # Need to set this, else it takes I don't know how long to timeout
633 # http://www.perlmonks.org/?node_id=618534
634
635 # http://search.cpan.org/~gaas/libwww-perl-6.04/lib/LWP/UserAgent.pm
636 # use LWP::UserAgent's get($url) since it returns an HTTP::Response code
637
638 my $response_obj = $ua->get($library_url.$command);
639
640 # $response_obj->content stores the content and $response_obj->code the HTTP response code
641 my $response_code = $response_obj->code();
642
643 if(LWP::Simple::is_success($response_code)) {# $response_code eq RC_OK) { # LWP::Simple::is_success($response_code)
644 $self->print_msg("*** Command $library_url$command\n", 3);
645 $self->print_msg("*** HTTP Response Status: $response_code - Complete.", 3);
646
647 # check the page content is as expected
648 my $response_content = $response_obj->content;
649 my $resultstr = $response_content;
650 $resultstr =~ s@.*gs_content\"\>@@s;
651 $resultstr =~ s@</div>.*@@s;
652
653 if($resultstr =~ m/$check_message_against_regex/) {#if($response_content =~ m/$check_message_against_regex/) {
654 $self->print_msg(" Response as expected.\n", 3);
655 $self->print_msg("@@@@@@ Got result:\n$resultstr\n", 4);
656 return 1;
657 } else {
658 # if we expect the collection to be inactive, then we'd be in silent mode: if so,
659 # don't print out the "ping did not succeed" response, but print out any other messages
660
661 # So we only suppress the ping col "did not succeed" response if we're in silent mode
662 # But if any message other than ping "did not succeed" is returned, we always print it
663 if($resultstr !~ m/did not succeed/ || !$silent) {#if($response_content !~ m/did not succeed/ || !$silent) {
664 $self->print_msg("\n\tBUT: command $library_url$command response UNEXPECTED.\n", 3);
665 $self->print_msg("*** Got message:\n$response_content.\n", 4);
666 $self->print_msg("*** Got result:\n$resultstr\n", 3);
667 }
668 return 0; # ping on a collection may "not succeed."
669 }
670 }
671 elsif(LWP::Simple::is_error($response_code)) { # method exported by LWP::Simple, along with HTTP::Status constants
672 # check the page content is as expected
673 if(defined $expected_error_code && $response_code == $expected_error_code) {
674 $self->print_msg(" Response status $response_code as expected.\n", 3);
675 } else {
676 $self->print_msg("*** Command $library_url$command\n");
677 $self->print_msg("*** Unexpected error. HTTP Response Status: $response_code - Failed.\n");
678 }
679 return 0; # return false, since the response_code was an error, expected or not
680 }
681 else {
682 $self->print_msg("*** Command $library_url$command\n");
683 $self->print_msg("*** Unexpected error. HTTP Response Status: $response_code - Failed.\n");
684 return 0;
685 }
686 }
687}
688
689# This method is now unused. Using ping_library instead to send the ping action to a
690# GS2/GS3 server. This method can be used more generally to test whether a URL is alive.
691# http://search.cpan.org/dist/libwww-perl/lib/LWP/Simple.pm
692# and http://www.perlmonks.org/?node_id=618534
693sub is_URL_active {
694 my $url = shift(@_); # gs3 or gs2 URL
695
696 my $status = 0;
697 if(defined $url) {
698 $ua->timeout(10); # set LWP useragent to 5s max timeout for testing the URL
699 # Need to set this, else it takes I don't know how long to timeout
700 # http://www.perlmonks.org/?node_id=618534
701
702 $status = LWP::Simple::head($url); # returns empty list of headers if it fails
703 # LWP::Simple::get($url) is more intensive, so don't need to do that
704 #print STDERR "**** $url is alive.\n" if $status;
705 }
706 return $status;
707}
708
709# Pinging seems to always return true, so this method doesn't work
710sub pingHost {
711 my $url = shift(@_); # gs3 or gs2 URL
712
713 my $status = 0;
714 if(defined $url) {
715 # Get just the domain. "http://localhost/gsdl?uq=332033495" becomes "localhost"
716 # "http://localhost/greenstone/cgi-bin/library.cgi" becomes "localhost" too
717
718 #my $host = $url;
719 #$host =~ s@^https?:\/\/(www.)?@@;
720 #$host =~ s@\/.*@@;
721 #print STDERR "**** HOST: $host\n";
722
723 # More robust way
724 # http://stackoverflow.com/questions/827024/how-do-i-extract-the-domain-out-of-an-url
725 my $uri = URI->new( $url );
726 my $host = $uri->host;
727
728 # Ping the host. http://perldoc.perl.org/Net/Ping.html
729 my $p = Net::Ping->new();
730 $status = $p->ping($host); # || 0. Appears to set to undef rather than 0
731 print STDERR "**** $host is alive.\n" if $status; #print "$host is alive.\n" if $p->ping($host);
732 $p->close();
733 }
734 # return whether pinging was a success or failure
735 return $status;
736}
737
7381;
Note: See TracBrowser for help on using the repository browser.