#!/usr/bin/perl -w
# ################################################################################ #
# #
# Name: loadDatabase.pl #
# Author: Aaron Brown #
# Contact: aaron@internet2.edu #
# Args: input file = The XML file containing the topology to add to the DB #
# --output = Outputs the normalized topology file #
# --db_dir = The directory of the Sleepycat Database #
# --db_file = The filename of the database #
# --uri = The uri of the MA to update #
# Purpose: Load the specified topology archive with the specified topology #
# #
# ################################################################################ #
use strict;
use XML::LibXML;
use File::Basename;
use Cwd;
my $dirname;
my $libdir;
# In the non-installed case, we need to figure out what the library is at
# compile time so that "use lib" doesn't fail. To do this, we enclose the
# calculation of it in a BEGIN block.
BEGIN {
# this value is set by the installation scripts
my $was_installed = 0;
if ($was_installed) {
# In this case, libdir needs to be set to the directory that the modules
# were installed to, and confdir needs to be set to the directory that
# logger.conf et al. were installed in. The installation script
# replaces the LIBDIR and CONFDIR portions with the actual directories
$libdir = "XXX_LIBDIR_XXX";
$dirname = "";
} else {
# we need a fully-qualified directory name in case we daemonize so that we
# can still access scripts or other files specified in configuration files
# in a relative manner. Also, we need to know the location in reference to
# the binary so that users can launch the daemon from wherever but specify
# scripts and whatnot relative to the binary.
$dirname = dirname($0);
if (!($dirname =~ /^\//)) {
$dirname = getcwd . "/" . $dirname;
}
$libdir = dirname($0)."/../../lib";
}
}
use lib "$libdir";
use perfSONAR_PS::Client::Topology::XMLDB;
use perfSONAR_PS::Client::Topology::MA;
use perfSONAR_PS::Topology::Common;
use perfSONAR_PS::Topology::ID;
use Log::Log4perl qw(:easy);
use Getopt::Long;
my %opts;
my $help_needed;
my $DEBUGFLAG;
sub usage() {
print "$0: loads a topology into a database replacing the existing topology elements.\n";
print " [--debug] [--help] [--output=NORMALIZED_TOPOLOGY_FILE] [--db_dir=DATABASE_DIRECTORY] [--db_filename=DATABASE_FILENAME] [--uri=REMOTE_TOPOLOGY_ARCHIVE] INPUT_FILE\n";
}
my $ok = GetOptions (
'debug' => \$DEBUGFLAG,
'output=s' => \$opts{OUTPUT_FILE},
'db_dir=s' => \$opts{DB_DIR},
'db_filename=s' => \$opts{DB_FILE},
'uri=s' => \$opts{URI},
'help' => \$help_needed
);
if (not $ok or $help_needed) {
usage();
exit(-1);
}
my $input_file = shift;
if (!defined $input_file or $input_file eq "" or ! -f $input_file) {
print "Error: you must specify an existing topology input file\n";
usage();
exit(-2);
}
if (!defined $opts{URI} and (!defined $opts{DB_DIR} or !defined $opts{DB_FILE})) {
print "Error: you must specify either a URI or the Database directory/filename\n";
usage();
exit(-3);
}
my $level;
if ($DEBUGFLAG) {
$level = $DEBUG;
} else {
$level = $INFO;
}
Log::Log4perl->easy_init($level);
my $logger = get_logger("perfSONAR_PS::Topology");
my ($status, $res);
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($input_file);
# The MA will normalize it for us, if we're not sending to the MA, we need to
# normalize unless the user has requested the normalized topology.
if (!defined $opts{URI} or $opts{URI} eq "" or defined $opts{OUTPUT_FILE}) {
($status, $res) = topologyNormalize($doc->documentElement());
if ($status != 0) {
$logger->debug("Error normalizing topology: $res");
exit(-1);
}
}
if (defined $opts{OUTPUT_FILE}) {
$doc->toFile($opts{OUTPUT_FILE});
}
my %ns;
%ns = getTopologyNamespaces();
# we probably should collect all the namespaces here
my @namespaces = $doc->documentElement()->getNamespaces();
foreach my $namespace (@namespaces) {
$ns{$namespace->prefix} = $namespace->getNamespaceURI;
}
my $client;
if (defined $opts{URI}) {
$client = new perfSONAR_PS::Client::Topology::MA($opts{URI});
} else {
if (!-d $opts{DB_DIR}) {
mkdir($opts{DB_DIR});
}
$client = new perfSONAR_PS::Client::Topology::XMLDB($opts{DB_DIR}, $opts{DB_FILE}, \%ns);
}
($status, $res) = $client->open;
if ($status != 0) {
$logger->debug("Couldn't open requested database");
exit(-1);
}
($status, $res) = $client->changeTopology("replace", $doc->documentElement());
if ($status != 0) {
print "Error adding topology: $res\n";
exit(-1);
}
exit(0);