in managementnode/lib/VCL/DataStructure.pm [787:937]
sub _automethod : Automethod {
my $self = shift;
my @args = @_;
my $method_name = $_;
# Make sure the function name begins with get_ or set_
my $mode;
my $data_identifier;
if ($method_name =~ /^(get|set)_(.*)/) {
# $mode stores either 'get' or 'set', data stores the requested data
$mode = $1;
$data_identifier = $2;
}
else {
notify($ERRORS{'WARNING'}, 0, "illegal subroutine name: $method_name");
return sub { };
}
# Determines whether or not warnings are shown if data is not initialized
my $show_warnings = 1;
# If set, make sure an argument was passed
my $set_data;
if ($mode =~ /set/ && defined $args[0]) {
$set_data = $args[0];
}
elsif ($mode =~ /set/) {
notify($ERRORS{'WARNING'}, 0, "data structure $method_name function was called without an argument");
return sub { };
}
elsif ($mode =~ /get/ && defined $args[0] && !$args[0]) {
$show_warnings = 0;
}
my $calling_subroutine = get_calling_subroutine();
# Check if the sub name is defined in the subroutine mappings hash
# Return if it isn't
if (!defined $SUBROUTINE_MAPPINGS{$data_identifier}) {
if ($calling_subroutine eq 'VCL::DataStructure::can') {
return;
}
else {
notify($ERRORS{'WARNING'}, 0, "unsupported subroutine name: $method_name");
return sub { };
}
}
elsif ($calling_subroutine eq 'VCL::DataStructure::can') {
return sub { };
}
# Get the hash path out of the subroutine mappings hash
my $hash_path = $SUBROUTINE_MAPPINGS{$data_identifier};
# Replace RESERVATION_ID with the actual reservation ID if it exists in the hash path
my $reservation_id = $self->reservation_id;
$reservation_id = 'undefined' if !defined($reservation_id);
$hash_path =~ s/RESERVATION_ID/$reservation_id/;
# Replace BLOCKREQUEST_ID with the actual blockrequest ID if it exists in the hash path
my $blockrequest_id = $self->blockrequest_id;
$blockrequest_id = 'undefined' if !defined($blockrequest_id);
$hash_path =~ s/BLOCKREQUEST_ID/$blockrequest_id/;
# Replace BLOCKTIME_ID with the actual blocktime ID if it exists in the hash path
my $blocktime_id = $self->blocktime_id;
$blocktime_id = 'undefined' if !defined($blocktime_id);
$hash_path =~ s/BLOCKTIME_ID/$blocktime_id/;
if ($mode =~ /get/) {
# Get the data from the request_data hash
# eval is required in order to interpolate the hash path before retrieving the data
my $key_defined = eval "defined $hash_path";
my $return_value;
# If log or sublog data was requested and not yet populated, attempt to retrieve it
if (!$key_defined && $data_identifier =~ /^(log_|sublog_)/) {
notify($ERRORS{'DEBUG'}, 0, "attempting to retrieve log data, requested data has not been initialized ($data_identifier)");
if ($self->get_log_data()) {
# Log data was retrieved, check if requested data is now populated
if (eval "defined $hash_path") {
$return_value = eval $hash_path;
notify($ERRORS{'DEBUG'}, 0, "log data was retrieved and corresponding data has been initialized for $method_name: $return_value");
}
else {
notify($ERRORS{'WARNING'}, 0, "log data was retrieved but corresponding data has not been initialized for $method_name: $hash_path", $self->request_data) if $show_warnings;
return sub { };
}
}
else {
notify($ERRORS{'WARNING'}, 0, "log data could not be retrieved");
return sub { };
}
}
elsif ($data_identifier =~ /^(management_node)/) {
# Get the management node info
# If no argument was specified get_management_node_info will return data for this management node
my $management_node_info_retrieved = get_management_node_info($args[0]);
unless ($management_node_info_retrieved) {
notify($ERRORS{'WARNING'}, 0, "failed to retrieve data for management node");
return sub { };
}
# The normal reservation management node data is stored in $ENV->{management_node_info}->{<identifier>}
# We don't want to overwrite this, but want to temporarily store the data retrieved
# This allows the $hash_path mechanism to work without alterations
# Temporarily overwrite this data by using 'local', and set it to the data just retrieved
# Once the current scope is exited, $ENV->{management_node_info} will return to its original value
local $ENV->{management_node_info} = $management_node_info_retrieved;
# Attempt to retrieve the value from the temporary data: $ENV->{management_node_info}->{KEY}
$return_value = eval $hash_path;
}
elsif (!$key_defined) {
if ($show_warnings && $hash_path !~ /(serverrequest|domain)/) {
notify($ERRORS{'WARNING'}, 0, "corresponding data has not been initialized for $method_name: $hash_path", $self->request_data);
}
return sub { };
}
else {
# Just attempt to retrieve the value from the hash path
$return_value = eval $hash_path;
}
if (!defined $return_value) {
if ($show_warnings && $method_name !~ /^(get_management_node_keys)$/) {
notify($ERRORS{'WARNING'}, 0, "corresponding data is undefined for $method_name: $hash_path");
}
return sub { };
}
# Return the data
return sub {$return_value;};
} ## end if ($mode =~ /get/)
elsif ($mode =~ /set/) {
eval $hash_path . ' = $set_data';
# Make sure the value was set in the hash
my $check_value = eval $hash_path;
if ($check_value eq $set_data) {
#notify($ERRORS{'DEBUG'}, 0, "data structure updated, hash path: $hash_path, data identifier: $data_identifier");
return sub {1;};
}
else {
notify($ERRORS{'WARNING'}, 0, "data structure could not be updated, hash path: $hash_path, data identifier: $data_identifier, data:\n" . format_data($set_data));
return sub {0;};
}
} ## end elsif ($mode =~ /set/) [ if ($mode =~ /get/)
} ## end sub _automethod :