source: main/trunk/greenstone2/bin/script/activate.pl@ 28185

Last change on this file since 28185 was 28185, checked in by kjdon, 11 years ago

we don't need to copy solr.xml from ext folder as its modified in the web folder. but we will generate the .in file to keep that in synch

  • Property svn:executable set to *
File size: 30.7 KB
Line 
1#!/usr/bin/perl -w
2
3###########################################################################
4#
5# activate.pl -- to be called after building a collection to activate it.
6#
7# A component of the Greenstone digital library software
8# from the New Zealand Digital Library Project at the
9# University of Waikato, New Zealand.
10#
11# Copyright (C) 2009 New Zealand Digital Library Project
12#
13# This program is free software; you can redistribute it and/or modify
14# it under the terms of the GNU General Public License as published by
15# the Free Software Foundation; either version 2 of the License, or
16# (at your option) any later version.
17#
18# This program is distributed in the hope that it will be useful,
19# but WITHOUT ANY WARRANTY; without even the implied warranty of
20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21# GNU General Public License for more details.
22#
23# You should have received a copy of the GNU General Public License
24# along with this program; if not, write to the Free Software
25# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26#
27###########################################################################
28
29
30# This program is designed to support the building process of Greenstone.
31# It deactivates the collection just built, if the web server is running
32# and is a persistent web server (or if the library_URL provided as
33# parameter to this script is of a currently running web server). It then
34# moves building to index, before activating the collection on the GS2 or
35# GS3 web server again if necessary.
36
37use Config;
38
39BEGIN {
40 die "GSDLHOME not set\n" unless defined $ENV{'GSDLHOME'};
41 die "GSDLOS not set\n" unless defined $ENV{'GSDLOS'};
42 unshift (@INC, "$ENV{'GSDLHOME'}/perllib");
43 unshift (@INC, "$ENV{'GSDLHOME'}/perllib/cpan");
44
45 # Adding cpan in, adds in its auto subfolder which conflicts with ActivePerl on Windows
46 # The auto folder has been moved into a perl-5.8 folder, and this will now be included
47 # only if the current version of perl is 5.8 (and not ActivePerl).
48 my $perl_dir;
49
50 # Note: $] encodes the version number of perl
51 if ($]>=5.010) {
52 $perl_dir="perl-5.".substr($],3,2);
53 }
54 elsif ($]>5.008) {
55 # perl 5.8.1 or above
56 $perl_dir = "perl-5.8";
57 }
58 elsif ($]>=5.008) {
59 # perl 5.8.1 or above
60 $perl_dir = "perl-5.8";
61 }
62 elsif ($]<5.008) {
63 # assume perl 5.6
64 $perl_dir = "perl-5.6";
65 }
66 else {
67 print STDERR "Warning: Perl 5.8.0 is not a maintained release.\n";
68 print STDERR " Please upgrade to a newer version of Perl.\n";
69 $perl_dir = "perl-5.8";
70 }
71
72 #if ($ENV{'GSDLOS'} !~ /^windows$/i) {
73 # Use push to put this on the end, so an existing XML::Parser will be used by default
74 if (-d "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir-mt" && $Config{usethreads}){
75 push (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir-mt");
76 }
77 else{
78 push (@INC, "$ENV{'GSDLHOME'}/perllib/cpan/$perl_dir");
79 }
80 #}
81
82}
83
84
85use strict;
86no strict 'refs'; # allow filehandles to be variables and vice versa
87no strict 'subs'; # allow barewords (eg STDERR) as function arguments
88
89use File::Basename;
90use File::Find;
91
92use HTTP::Response;
93use LWP::Simple qw($ua !head); # import useragent object as $ua from the full LWP to use along with LWP::Simple
94 # don't import LWP::Simple's head function by name since it can conflict with CGI:head())
95#use CGI qw(:standard); # then only CGI.pm defines a head()
96use Net::Ping;
97use URI;
98
99use colcfg;
100use scriptutil;
101use util;
102#use enum;
103
104# enumerations in perl, http://stackoverflow.com/questions/473666/does-perl-have-an-enumeration-type
105# Unfortunately, not part of perl's core
106#use enum qw(LEVEL_NONE LEVEL_ERROR LEVEL_INFO LEVEL_DEBUG); # debugging levels NONE == 0, ERROR=1 INFO=2 DEBUG=3
107
108# global variables
109#my $default_verbosity = LEVEL_ERROR; # by default we display basic error messages
110
111my $default_verbosity = 2; # by default we display basic error and info messages
112
113sub print_task_msg {
114 my ($task_msg, $verbosity_setting) = @_;
115
116 $verbosity_setting = $default_verbosity unless $verbosity_setting;
117 #$verbosity_setting = 1 unless defined $verbosity;
118 if($verbosity_setting >= 1) {
119 print STDERR "\n";
120 print STDERR "************************\n";
121 print STDERR "* $task_msg\n";
122 print STDERR "************************\n";
123 }
124}
125
126# Prints messages if the verbosity is right. Does not add new lines.
127sub print_msg {
128 my ($msg, $min_verbosity, $verbosity_setting) = @_;
129
130 # only display error messages if the current
131 # verbosity setting >= the minimum verbosity level
132 # needed for that message to be displayed.
133
134 $verbosity_setting = $default_verbosity unless defined $verbosity_setting;
135 $min_verbosity = 1 unless defined $min_verbosity;
136 if($verbosity_setting >= $min_verbosity) { # by default display all 1 messages
137 print STDERR "$msg";
138 }
139}
140
141# Method to send a command to a GS2 or GS3 library_URL
142# the commands used in this script can be activate, deactivate, ping,
143# and is-persistent (is-persistent only implemented for GS2).
144sub config {
145 my ($library_url, $command, $check_message_against_regex, $site, $expected_error_code) = @_;
146 # Gatherer.java's configGS3Server doesn't use the site variable
147 # so we don't have to either
148
149 # for GS2, getting the HTTP status isn't enough, we need to read the output
150 # since this is what CollectionManager.config() stipulates.
151 # Using LWP::UserAgent::get($url) for this
152
153 if(!defined $library_url) {
154 return 0;
155 }
156 else {
157 $ua->timeout(5); # set LWP useragent to 5s max timeout for testing the URL
158 # Need to set this, else it takes I don't know how long to timeout
159 # http://www.perlmonks.org/?node_id=618534
160
161 # http://search.cpan.org/~gaas/libwww-perl-6.04/lib/LWP/UserAgent.pm
162 # use LWP::UserAgent's get($url) since it returns an HTTP::Response code
163
164 my $response_obj = $ua->get( $library_url.$command);
165
166 # $response_obj->content stores the content and $response_obj->code the HTTP response code
167 my $response_code = $response_obj->code();
168
169 if(LWP::Simple::is_success($response_code)) {# $response_code eq RC_OK) { # LWP::Simple::is_success($response_code)
170 &print_msg("*** Command $library_url$command\n", 3);
171 &print_msg("*** HTTP Response Status: $response_code - Complete.", 3);
172
173 # check the page content is as expected
174 my $response_content = $response_obj->content;
175 if($response_content =~ m/$check_message_against_regex/) {
176 &print_msg(" Response as expected.\n", 3);
177 return 1;
178 } else {
179 &print_msg("\n\tBUT: command $library_url$command response UNEXPECTED.\n", 3);
180 &print_msg("*** Got message:\n$response_content.\n", 4);
181 return 0; # ping on a collection may "not succeed."
182 }
183 }
184 elsif(LWP::Simple::is_error($response_code)) { # method exported by LWP::Simple, along with HTTP::Status constants
185 # check the page content is as expected
186 if(defined $expected_error_code && $response_code == $expected_error_code) {
187 &print_msg(" Response status $response_code as expected.\n", 3);
188 } else {
189 &print_msg("*** Command $library_url$command\n");
190 &print_msg("*** Unexpected error. HTTP Response Status: $response_code - Failed.\n");
191 }
192 return 0; # return false, since the response_code was an error, expected or not
193 }
194 else {
195 &print_msg("*** Command $library_url$command\n");
196 &print_msg("*** Unexpected error. HTTP Response Status: $response_code - Failed.\n");
197 return 0;
198 }
199 }
200}
201
202sub deactivate_collection {
203 my ($library_url, $gs_mode, $qualified_collection, $site) = @_;
204
205 if($gs_mode eq "gs2") {
206 my $DEACTIVATE_COMMAND = "?a=config&cmd=release-collection&c=";
207 my $check_message_against_regex = q/configured release-collection/;
208 config($library_url, $DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
209 }
210 elsif ($gs_mode eq "gs3") {
211 my $DEACTIVATE_COMMAND = "?a=s&sa=d&st=collection&sn=";
212 my $check_message_against_regex = "collection: $qualified_collection deactivated";
213 config($library_url, $DEACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex, $site);
214 }
215}
216
217sub activate_collection {
218 my ($library_url, $gs_mode, $qualified_collection, $site) = @_;
219
220 if($gs_mode eq "gs2") {
221 my $ACTIVATE_COMMAND = "?a=config&cmd=add-collection&c=";
222 my $check_message_against_regex = q/configured add-collection/;
223 config($library_url, $ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex);
224 }
225 elsif ($gs_mode eq "gs3") {
226 my $ACTIVATE_COMMAND = "?a=s&sa=a&st=collection&sn=";
227 my $check_message_against_regex = "collection: $qualified_collection activated";
228 config($library_url, $ACTIVATE_COMMAND.$qualified_collection, $check_message_against_regex, $site);
229 }
230}
231
232sub ping {
233 my ($library_url, $command, $gs_mode, $site) = @_;
234
235 # If the GS server is not running, we *expect* to see a "500" status code.
236 # If the GS server is running, then "Ping" ... "succeeded" is expected on success.
237 # When pinging an inactive collection, it will say it did "not succeed". This is
238 # a message of interest to return.
239 my $check_responsemsg_against_regex = q/(succeeded)/;
240 my $expected_error_code = 500;
241 return config($library_url, $command, $check_responsemsg_against_regex, $site, $expected_error_code);
242}
243
244# send a pingaction to the GS library. General server-level ping.
245sub ping_library {
246 my ($library_url, $gs_mode, $site) = @_;
247
248 my $command = "";
249 if($gs_mode eq "gs2") {
250 $command = "?a=ping";
251 }
252 elsif ($gs_mode eq "gs3") {
253 $command = "?a=s&sa=ping";
254 }
255 return &ping($library_url, $command, $gs_mode, $site);
256}
257
258
259# send a pingaction to a collection in GS library to check if it's active
260sub ping_library_collection {
261 my ($library_url, $gs_mode, $qualified_collection, $site) = @_;
262
263 my $command = "";
264 if($gs_mode eq "gs2") {
265 $command = "?a=ping&c=$qualified_collection";
266 }
267 elsif ($gs_mode eq "gs3") {
268 $command = "?a=s&sa=ping&st=collection&sn=$qualified_collection";
269 }
270 return &ping($library_url, $command, $gs_mode, $site);
271}
272
273# return true if server is persistent, by calling is-persistent on library_url
274# this is only for GS2, since the GS3 server is always persistent
275sub is_persistent {
276 my ($library_url, $gs_mode) = @_;
277
278 if($gs_mode eq "gs3") { # GS3 server is always persistent
279 return 1;
280 }
281
282 my $command = "?a=is-persistent";
283 my $check_responsemsg_against_regex = q/true/; # isPersistent: true versus isPersistent: false
284 return config($library_url, $command, $check_responsemsg_against_regex);
285}
286
287sub get_library_URL {
288 my $gs_mode = shift(@_); # gs3 or gs2
289
290 # If we get here, we are dealing with a server included with GS.
291 # For GS3, we ask ant for the library URL.
292 # For GS2, we derive the URL from the llssite.cfg file.
293
294 my $url = undef;
295
296 if($gs_mode eq "gs2") {
297 my $llssite_cfg = &FileUtils::filenameConcatenate($ENV{'GSDLHOME'}, "llssite.cfg");
298
299 if(-f $llssite_cfg) {
300 # check llssite.cfg for line with url property
301 # for server.exe also need to use portnumber and enterlib properties
302
303 # Read in the entire contents of the file in one hit
304 if (!open (FIN, $llssite_cfg)) {
305 &print_msg("activate.pl::get_library_URL failed to open $llssite_cfg ($!)\n");
306 return undef;
307 }
308
309 my $contents;
310 sysread(FIN, $contents, -s FIN);
311 close(FIN);
312
313 my @lines = split(/[\n\r]+/, $contents); # split on carriage-returns and/or linefeeds
314 my $enterlib = "";
315 my $portnumber = ""; # will remain empty (implicit port 80) unless it's specifically been assigned
316
317 foreach my $line (@lines) {
318 if($line =~ m/^url=(.*)$/) {
319 $url = $1;
320 } elsif($line =~ m/^enterlib=(.*)$/) {
321 $enterlib = $1;
322 } elsif($line =~ m/^portnumber=(.*)$/) {
323 $portnumber = $1;
324 }
325 }
326
327 if(!$url) {
328 return undef;
329 }
330 elsif($url eq "URL_pending") { # library is not running
331 # do not process url=URL_pending in the file, since for server.exe
332 # this just means the Enter Library button hasn't been pressed yet
333 $url = undef;
334 }
335 else {
336 # In the case of server.exe, need to do extra work to get the proper URL
337 # But first, need to know whether we're indeed dealing with server.exe:
338
339 # compare the URL's domain to the full URL
340 # E.g. for http://localhost:8383/greenstone3/cgi-bin, the domain is localhost:8383
341 my $uri = URI->new( $url );
342 my $host = $uri->host;
343 #print STDERR "@@@@@ host: $host\n";
344 if($url =~ m/http:\/\/$host(\/)?$/) {
345 #if($url !~ m/http:\/\/$host:$portnumber(\/)?/ || $url =~ m/http:\/\/$host(\/)?$/) {
346 # (if the URL does not contain the portnumber, OR if the port is implicitly 80 and)
347 # If the domain with http:// prefix is completely the same as the URL, assume server.exe
348 # then the actual URL is the result of suffixing the port and enterlib properties in llssite.cfg
349 $url = $url.":".$portnumber.$enterlib;
350 } # else, apache web server
351
352 }
353 }
354 } elsif($gs_mode eq "gs3") {
355 # Either check build.properties for tomcat.server, tomcat.port and app.name (and default servlet name).
356 # app.name is stored in app.path by build.xml. Need to move app.name in build.properties from build.xml
357
358 # Or, run the new target get-default-servlet-url
359 # the output can look like:
360 #
361 # Buildfile: build.xml
362 # [echo] os.name: Windows Vista
363 #
364 # get-default-servlet-url:
365 # [echo] http://localhost:8383/greenstone3/library
366 # BUILD SUCCESSFUL
367 # Total time: 0 seconds
368
369 #my $output = qx/ant get-default-servlet-url/; # backtick operator, to get STDOUT (else 2>&1)
370 # see http://stackoverflow.com/questions/799968/whats-the-difference-between-perls-backticks-system-and-exec
371
372 # The get-default-servlet-url ant target can be run from anywhere by specifying the
373 # location of GS3's ant build.xml buildfile. Activate.pl can be run from anywhere for GS3
374 # GSDL3SRCHOME will be set for GS3 by gs3-setup.sh, a step that would have been necessary
375 # to run the activate.pl script in the first place
376 my $perl_command = "ant -buildfile \"$ENV{'GSDL3SRCHOME'}/build.xml\" get-default-servlet-url";
377
378 if (open(PIN, "$perl_command |")) {
379 while (defined (my $perl_output_line = <PIN>)) {
380 if($perl_output_line =~ m@http:\/\/(\S*)@) { # grab all the non-whitespace chars
381 $url="http://".$1;
382 }
383 }
384 close(PIN);
385 } else {
386 &print_msg("activate.pl::get_library_URL: Failed to run $perl_command to work out library URL for $gs_mode\n");
387 }
388 }
389
390 # either the url is still undef or it is now set
391 #print STDERR "\n@@@@@ final URL:|$url|\n" if $url;
392 #print STDERR "\n@@@@@ URL still undef\n" if !$url;
393 return $url;
394}
395
396### UNUSED METHODS TO MOVE TO util.pm?
397
398# This method is now unused. Using ping_library instead to send the ping action to a
399# GS2/GS3 server. This method can be used more generally to test whether a URL is alive.
400# http://search.cpan.org/dist/libwww-perl/lib/LWP/Simple.pm
401# and http://www.perlmonks.org/?node_id=618534
402sub is_URL_active {
403 my $url = shift(@_); # gs3 or gs2 URL
404
405 my $status = 0;
406 if(defined $url) {
407 $ua->timeout(5); # set LWP useragent to 5s max timeout for testing the URL
408 # Need to set this, else it takes I don't know how long to timeout
409 # http://www.perlmonks.org/?node_id=618534
410
411 $status = LWP::Simple::head($url); # returns empty list of headers if it fails
412 # LWP::Simple::get($url) is more intensive, so don't need to do that
413 #print STDERR "**** $url is alive.\n" if $status;
414 }
415 return $status;
416}
417
418# Pinging seems to always return true, so this method doesn't work
419sub pingHost {
420 my $url = shift(@_); # gs3 or gs2 URL
421
422 my $status = 0;
423 if(defined $url) {
424 # Get just the domain. "http://localhost/gsdl?uq=332033495" becomes "localhost"
425 # "http://localhost/greenstone/cgi-bin/library.cgi" becomes "localhost" too
426
427 #my $host = $url;
428 #$host =~ s@^http:\/\/(www.)?@@;
429 #$host =~ s@\/.*@@;
430 #print STDERR "**** HOST: $host\n";
431
432 # More robust way
433 # http://stackoverflow.com/questions/827024/how-do-i-extract-the-domain-out-of-an-url
434 my $uri = URI->new( $url );
435 my $host = $uri->host;
436
437 # Ping the host. http://perldoc.perl.org/Net/Ping.html
438 my $p = Net::Ping->new();
439 $status = $p->ping($host); # || 0. Appears to set to undef rather than 0
440 print STDERR "**** $host is alive.\n" if $status; #print "$host is alive.\n" if $p->ping($host);
441 $p->close();
442 }
443 # return whether pinging was a success or failure
444 return $status;
445}
446
447
448# Most of the arguments are familiar from the building scripts like buildcol.pl
449# The special optional argument -library_url is for when we're dealing with a web
450# library server such as an apache that's separate from any included with GS2.
451# In such a case, this script's caller should pass in -library_url <URL>.
452#
453# $site argument must be specified in the cmdline for collectionConfig.xml to get
454# generated which makes $gs_mode=gs3, else collect.cfg gets generated and $gs_mode=gs2
455sub main
456{
457 my ($argc,@argv) = @_;
458
459 if (($argc==0) || (($argc==1) && ($argv[0] =~ m/^--?h(elp)?$/))) {
460 my ($progname) = ($0 =~ m/^.*[\/|\\](.*?)$/);
461
462
463 print STDERR "\n";
464 print STDERR "Usage: $progname [-collectdir c -builddir b -indexdir i -site s -removeold -keepold -verbosity v\n";
465 print STDERR "\t-library_url URL] <[colgroup/]collection>\n";
466 print STDERR "\n";
467
468 exit(-1);
469 }
470
471 # get the collection details
472 my $qualified_collection = pop @argv; # qualified collection
473
474 my $collect_dir = undef; #"collect"; # can't be "collect" when only -site is provided for GS3
475 my $build_dir = undef;
476 my $index_dir = undef;
477 my $site = undef;
478
479 my $removeold = 0;
480 my $keepold = 0;
481 my $incremental = 0; # used by solr
482
483 my $library_url = undef; # to be specified on the cmdline if not using a GS-included web server
484
485 while (my $arg = shift @argv) {
486 if ($arg eq "-collectdir") {
487 $collect_dir = shift @argv;
488 }
489 elsif ($arg eq "-builddir") {
490 $build_dir = shift @argv;
491 }
492 elsif ($arg eq "-indexdir") {
493 $index_dir = shift @argv;
494 }
495 elsif ($arg eq "-site") {
496 $site = shift @argv;
497 }
498 elsif ($arg eq "-removeold") {
499 $removeold = 1;
500 }
501 elsif ($arg eq "-keepold") {
502 $keepold = 1;
503 }
504 elsif ($arg eq "-incremental") {
505 $incremental = 1;
506 }
507 elsif ($arg eq "-library_url") {
508 $library_url = shift @argv;
509 }
510 elsif ($arg eq "-verbosity") {
511 $default_verbosity = shift @argv; # global variable
512
513 # ensure we're working with ints not strings (int context not str context), in case verbosity=0
514 # http://stackoverflow.com/questions/288900/how-can-i-convert-a-string-to-a-number-in-perl
515 $default_verbosity = int($default_verbosity || 0); ### is this the best way?
516 }
517 }
518
519 # work out the building and index dirs
520 my $collection_dir = &util::resolve_collection_dir($collect_dir, $qualified_collection, $site);
521 $build_dir = &FileUtils::filenameConcatenate($collection_dir, "building") unless (defined $build_dir);
522 $index_dir = &FileUtils::filenameConcatenate($collection_dir, "index") unless (defined $index_dir);
523
524 &print_task_msg("Running Collection Activation Stage");
525
526 # get and check the collection name
527 if ((&colcfg::use_collection($site, $qualified_collection, $collect_dir)) eq "") {
528 &print_msg("Unable to use collection \"$qualified_collection\" within \"$collect_dir\"\n");
529 exit -1;
530 }
531
532 # Read in the collection configuration file.
533 # Beware: Only if $site is specified in the cmdline does collectionConfig.xml get
534 # generated and does $gs_mode=gs3, else collect.cfg gets generated and $gs_mode=gs2
535 my $gs_mode = "gs2";
536 if ((defined $site) && ($site ne "")) { # GS3
537 $gs_mode = "gs3";
538 }
539 my $collect_cfg_filename = &colcfg::get_collect_cfg_name(STDERR, $gs_mode);
540 my $collectcfg = &colcfg::read_collection_cfg ($collect_cfg_filename,$gs_mode);
541
542 # look for build.cfg/buildConfig.xml
543 my $build_cfg_filename ="";
544
545 if ($gs_mode eq "gs2") {
546 $build_cfg_filename = &FileUtils::filenameConcatenate($build_dir,"build.cfg");
547 } else {
548 $build_cfg_filename = &FileUtils::filenameConcatenate($build_dir, "buildConfig.xml");
549 # gs_mode is GS3. Set the site now if this was not specified as cmdline argument
550 #$site = "localsite" unless defined $site;
551 }
552
553 # We need to know the buildtype for Solr.
554 # Any change of indexers is already detected and handled by the calling code (buildcol or
555 # full-rebuild), so that at this stage the config file's buildtype reflects the actual buildtype.
556
557 # From buildcol.pl we use searchtype for determining buildtype, but for old versions, use buildtype
558 my $buildtype;
559 if (defined $collectcfg->{'buildtype'}) {
560 $buildtype = $collectcfg->{'buildtype'};
561 } elsif (defined $collectcfg->{'searchtypes'} || defined $collectcfg->{'searchtype'}) {
562 $buildtype = "mgpp";
563 } else {
564 $buildtype = "mg"; #mg is the default
565 }
566
567 # can't do anything without a build directory with something in it to move into index
568 # Except if we're (doing incremental) building for solr, where we want to still
569 # activate and deactivate collections including for the incremental case
570 if(!&FileUtils::directoryExists($build_dir)) {
571 &print_msg("No building folder at $build_dir to move to index.\n");
572 exit -1 unless ($buildtype eq "solr"); #&& $incremental);
573 } elsif (&FileUtils::isDirectoryEmpty($build_dir)) {
574 &print_msg("Nothing in building folder $build_dir to move into index folder.\n");
575 exit -1 unless ($buildtype eq "solr"); #&& $incremental);
576 }
577
578
579 my $solr_server;
580 my @corenames = ();
581 if($buildtype eq "solr") { # start up the jetty server
582 my $solr_ext = $ENV{'GEXT_SOLR'}; # from solr_passes.pl
583 unshift (@INC, "$solr_ext/perllib");
584 require solrserver;
585
586 # Solr cores are named without taking the collection-group name into account, since solr
587 # is used for GS3 and GS3 doesn't use collection groups but has the site concept instead
588 my ($colname, $colgroup) = &util::get_collection_parts($qualified_collection);
589
590 # See solrbuilder.pm to get the indexing levels (document, section) from the collectcfg file
591 # Used to generate core names from them and remove cores by name
592 foreach my $level ( @{$collectcfg->{'levels'}} ){
593 my ($pindex) = $level =~ /^(.)/;
594 my $indexname = $pindex."idx";
595 push(@corenames, "$site-$colname-$indexname"); #"$site-$colname-didx", "$site-$colname-sidx"
596 }
597
598 # If the Solr/Jetty server is not already running, the following starts
599 # it up, and only returns when the server is "reading and listening"
600 $solr_server = new solrserver($build_dir);
601 $solr_server->start();
602
603 # We'll be moving building to index. For solr collection, there's further
604 # special processing to make a corresponding change to the solr.xml
605 # by removing the temporary building cores and (re)creating the index cores
606 }
607
608 # Now the logic in GLI's CollectionManager.java (processComplete()
609 # and installCollection()) and Gatherer.configGS3Server().
610
611 # 1. Get library URL
612
613 # For web servers that are external to a Greenstone installation,
614 # the user can pass in their web server's library URL.
615 # For web servers included with GS (like tomcat for GS3 and server.exe
616 # and apache for GS2), we work out the library URL:
617 if(!$library_url) {
618 $library_url = &get_library_URL($gs_mode); # returns undef if no server is running
619 }
620
621 # CollectionManager's installCollection phase in GLI
622 # 2. Ping the library URL, and if it's a persistent server and running, release the collection
623
624 my $is_persistent_server = undef;
625 if($library_url) { # undef if no valid server URL
626
627 &print_msg("Pinging $library_url\n");
628 if (&ping_library($library_url, $gs_mode, $site)) { # server running
629
630 # server is running, so release the collection if
631 # the server is persistent and the collection is active
632 &print_msg("Checking if Greenstone server is persistent\n");
633 $is_persistent_server = &is_persistent($library_url, $gs_mode);
634
635 if ($is_persistent_server) { # only makes sense to issue activate and deactivate cmds to a persistent server
636
637 &print_msg("Checking if the collection $qualified_collection is already active\n");
638 my $collection_active = &ping_library_collection($library_url, $gs_mode, $qualified_collection, $site);
639
640 if ($collection_active) {
641 &print_msg("De-activating collection $qualified_collection\n");
642 &deactivate_collection($library_url, $gs_mode, $qualified_collection, $site);
643 }
644 else {
645 &print_msg("Collection is not active => No need to deactivate\n");
646 }
647 }
648 else {
649 &print_msg("Server is not persistent => No need to deactivate collection\n");
650 }
651 }
652 else {
653 &print_msg("No response to Ping => Taken to mean server is not running\n");
654 }
655
656 }
657
658 # 3. Do all the moving building to index stuff now
659
660 # If removeold: replace index dir with building dir.
661 # If keepold: move building's contents into index, where only duplicates will get deleted.
662 # removeold and keepold can't both be on at the same time
663 # incremental becomes relevant for solr, though it was irrelevant to what activate.pl does (moving building to index)
664 my $incremental_mode;
665 ($removeold, $keepold, $incremental, $incremental_mode) = &scriptutil::check_removeold_and_keepold($removeold, $keepold,
666 $incremental,
667 $build_dir, # checkdir. Usually archives or export to be deleted. activate.pl deletes building
668 $collectcfg);
669
670 if($removeold) {
671
672 if(&FileUtils::directoryExists($index_dir)) {
673 &print_task_msg("Removing \"index\"");
674
675 if ($buildtype eq "solr") {
676 # if solr, remove any cores that are using the index_dir before deleting this dir
677 foreach my $corename (@corenames) {
678 $solr_server->admin_unload_core($corename);
679 }
680 }
681
682 &FileUtils::removeFilesRecursive($index_dir);
683
684 # Wait for a couple of seconds, just for luck
685 sleep 2;
686
687 if (&FileUtils::directoryExists($index_dir)) {
688 &print_msg("The index directory $index_dir could not be deleted.\n"); # CollectionManager.Index_Not_Deleted
689 }
690 }
691
692 # if remote GS server: gliserver.pl would call activate.pl to activate
693 # the collection at this point since activate.pl lives on the server side
694
695 if ($buildtype eq "solr") {
696 # if solr, remove any cores that are using the building_dir before moving this dir onto index
697 foreach my $corename (@corenames) {
698 $solr_server->admin_unload_core("building-$corename");
699 }
700 }
701
702 # Move the building directory to become the new index directory
703 &print_task_msg("Moving \"building\" -> \"index\"");
704 &FileUtils::moveFiles($build_dir, $index_dir);
705 if(&FileUtils::directoryExists($build_dir) || !&FileUtils::directoryExists($index_dir)) {
706 &print_msg("Could not move $build_dir to $index_dir.\n"); # CollectionManager.Build_Not_Moved
707 }
708 }
709 elsif ($keepold || $incremental) {
710 if ($buildtype eq "solr") {
711 # if solr, remove any cores that may be using the building_dir before moving this dir onto index
712 foreach my $corename (@corenames) {
713 $solr_server->admin_unload_core("building-$corename") if $solr_server->admin_ping_core("building-$corename");
714 }
715 }
716
717 # Copy just the contents of building dir into the index dir, overwriting
718 # existing files, but don't replace index with building.
719 &print_task_msg("Moving \"building\" -> \"index\"");
720 &FileUtils::moveDirectoryContents($build_dir, $index_dir);
721 }
722
723 if ($buildtype eq "solr") {
724 # Call CREATE action to get the old cores pointing to the index folder
725 foreach my $corename (@corenames) {
726 if($removeold) {
727 # Call CREATE action to get all cores pointing to the index folder, since building is now index
728 $solr_server->admin_create_core($corename, $index_dir);
729
730 } elsif ($keepold || $incremental) {
731 # Call RELOAD core. Should already be using the index_dir directory for $keepold and $incremental case
732
733 # Ping to see if corename exists, if it does, reload, else create
734 if ($solr_server->admin_ping_core($corename)) {
735 $solr_server->admin_reload_core($corename);
736 } else {
737 $solr_server->admin_create_core($corename, $index_dir);
738 }
739 }
740 }
741
742 # regenerate the solr.xml.in from solr.xml in case we are working off a dvd.
743 $solr_server->solr_xml_to_solr_xml_in();
744 }
745
746 # 4. Ping the library URL, and if it's a persistent server and running, activate the collection again
747
748 # Check for success: if building does not exist OR is empty
749 if(!&FileUtils::directoryExists($build_dir) || &FileUtils::isDirectoryEmpty($build_dir)) {
750
751 if($library_url) { # undef if no valid server URL
752
753 &print_msg("Pinging $library_url\n");
754 if (&ping_library($library_url, $gs_mode, $site)) { # server running
755
756 # don't need to work out persistency of server more than once, since the libraryURL hasn't changed
757 if (!defined $is_persistent_server) {
758 &print_msg("Checking if Greenstone server is persistent\n");
759 $is_persistent_server = &is_persistent($library_url, $gs_mode);
760 }
761
762
763 if ($is_persistent_server) { # persistent server, so can try activating collection
764
765 &print_msg("Checking if the collection $qualified_collection is not already active\n");
766 my $collection_active = &ping_library_collection($library_url, $gs_mode, $qualified_collection, $site);
767
768 if (!$collection_active) {
769 &print_msg("Activating collection $qualified_collection\n");
770 &activate_collection($library_url, $gs_mode, $qualified_collection, $site);
771
772 # unless an error occurred, the collection should now be active:
773 $collection_active = &ping_library_collection($library_url, $gs_mode, $qualified_collection, $site);
774 if(!$collection_active) {
775 &print_msg("ERROR: collection $qualified_collection did not get activated\n");
776 }
777 }
778 else {
779 &print_msg("Collection is not active => No need to deactivate\n");
780 }
781 }
782 else {
783 &print_msg("Server is not persistent => No need to deactivate collection\n");
784 }
785 }
786 else {
787 &print_msg("No response to Ping => Taken to mean server is not running\n");
788 }
789 }
790 } else { # installcollection failed
791 #CollectionManager.Preview_Ready_Failed
792 &print_msg("Building directory is not empty or still exists. Failed to properly move $build_dir to $index_dir.\n");
793 }
794
795 &print_msg("\n");
796
797 if($buildtype eq "solr") {
798 if ($solr_server->explicitly_started()) {
799 $solr_server->stop();
800 }
801 }
802}
803
804&main(scalar(@ARGV),@ARGV);
Note: See TracBrowser for help on using the repository browser.