Author: arkurth
Date: Mon Apr  6 17:54:19 2009
New Revision: 762438

URL: http://svn.apache.org/viewvc?rev=762438&view=rev
Log:
VCL-122
Added functionality to DataStructure.pm allowing it to get/set data from the 
log table.

Added DataStructure.pm::update_log_ending_DataStructure(). This sub will 
replace utils.pm::update_log_ending(). The new sub has access to all of the 
DataStructure data and adds logic to set the log.ending value to "failedtest" 
instead of "failed" under any of these conditions:
-imagerevision.production = 0
-image is only assigned to a single group named newimages-*
-state = reload
-state = to* (tomaintenance...)
-state = makeproduction
-state = *hpc*
-state = image

Modified:
    incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm

Modified: incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm
URL: 
http://svn.apache.org/viewvc/incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm?rev=762438&r1=762437&r2=762438&view=diff
==============================================================================
--- incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm (original)
+++ incubator/vcl/trunk/managementnode/lib/VCL/DataStructure.pm Mon Apr  6 
17:54:19 2009
@@ -141,6 +141,28 @@
 $SUBROUTINE_MAPPINGS{request_state_name}     = 
'$self->request_data->{state}{name}';
 $SUBROUTINE_MAPPINGS{request_laststate_name} = 
'$self->request_data->{laststate}{name}';
 
+$SUBROUTINE_MAPPINGS{log_id} = '$self->request_data->{log}{id}';
+$SUBROUTINE_MAPPINGS{log_userid} = '$self->request_data->{log}{userid}';
+$SUBROUTINE_MAPPINGS{log_nowfuture} = '$self->request_data->{log}{nowfuture}';
+$SUBROUTINE_MAPPINGS{log_start} = '$self->request_data->{log}{start}';
+$SUBROUTINE_MAPPINGS{log_loaded} = '$self->request_data->{log}{loaded}';
+$SUBROUTINE_MAPPINGS{log_initialend} = 
'$self->request_data->{log}{initialend}';
+$SUBROUTINE_MAPPINGS{log_finalend} = '$self->request_data->{log}{finalend}';
+$SUBROUTINE_MAPPINGS{log_wasavailable} = 
'$self->request_data->{log}{wasavailable}';
+$SUBROUTINE_MAPPINGS{log_ending} = '$self->request_data->{log}{ending}';
+$SUBROUTINE_MAPPINGS{log_requestid} = '$self->request_data->{log}{requestid}';
+$SUBROUTINE_MAPPINGS{log_computerid} = 
'$self->request_data->{log}{computerid}';
+$SUBROUTINE_MAPPINGS{log_remoteIP} = '$self->request_data->{log}{remoteIP}';
+$SUBROUTINE_MAPPINGS{log_imageid} = '$self->request_data->{log}{imageid}';
+$SUBROUTINE_MAPPINGS{log_size} = '$self->request_data->{log}{size}';
+
+$SUBROUTINE_MAPPINGS{sublog_imageid} = '$self->request_data->{log}{imageid}';
+$SUBROUTINE_MAPPINGS{sublog_imagerevisionid} = 
'$self->request_data->{log}{imagerevisionid}';
+$SUBROUTINE_MAPPINGS{sublog_computerid} = 
'$self->request_data->{log}{computerid}';
+$SUBROUTINE_MAPPINGS{sublog_IPaddress} = 
'$self->request_data->{log}{IPaddress}';
+$SUBROUTINE_MAPPINGS{sublog_managementnodeid} = 
'$self->request_data->{log}{managementnodeid}';
+$SUBROUTINE_MAPPINGS{sublog_predictivemoduleid} = 
'$self->request_data->{log}{predictivemoduleid}';
+
 #$SUBROUTINE_MAPPINGS{request_reservationid} = 
'$self->request_data->{RESERVATIONID}';
 $SUBROUTINE_MAPPINGS{reservation_id} = '$self->request_data->{RESERVATIONID}';
 
@@ -606,7 +628,24 @@
                # 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";
-               if (!$key_defined) {
+               
+               # 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") {
+                                       notify($ERRORS{'WARNING'}, 0, "log data 
was retrieved but corresponding data has not been initialized for $method_name: 
$hash_path", $self->request_data);
+                                       return sub { };
+                               }
+                       }
+                       else {
+                               notify($ERRORS{'WARNING'}, 0, "log data could 
not be retrieved");
+                               return sub { };
+                       }
+               }
+               elsif (!$key_defined) {
                        notify($ERRORS{'WARNING'}, 0, "corresponding data has 
not been initialized for $method_name: $hash_path", $self->request_data);
                        return sub { };
                }
@@ -1250,6 +1289,267 @@
 
 #/////////////////////////////////////////////////////////////////////////////
 
+=head2 get_log_data
+
+ Parameters  : log ID (optional)
+ Returns     : hash reference
+ Description : Retrieves data from the log and sublog tables for the log ID
+               either specified via an argument or the log ID for the
+                                       reservation represented by the 
DataStructure object.
+
+=cut
+
+sub get_log_data {
+       my $self;
+       my $argument = shift;
+       my $request_log_id;
+       
+       # Check if subroutine was called as an object method
+       if (ref($argument) =~ /DataStructure/) {
+               # Subroutine was called as an object method, get next argument
+               $self = $argument;
+               $argument = shift;
+               
+               # If argument wasn't passed, attempt to get the log id from 
this DataStructure object
+               if (!$argument) {
+                       # Get the log id and make sure it is set
+                       $request_log_id = $self->get_request_log_id();
+                       if (!$request_log_id) {
+                               notify($ERRORS{'WARNING'}, 0, "log id was not 
passed as an argument and could not be retrieved from the existing 
DataStructure object");
+                               return;
+                       }
+               }
+               else {
+                       $request_log_id = $argument;
+               }
+       }
+       else {
+               $request_log_id = $argument;
+               
+               # Make sure log id was determined and is valid
+               if (!$request_log_id) {
+                       notify($ERRORS{'WARNING'}, 0, "log id was not passed as 
an argument and subroutine was not called as an object method");
+                       return;
+               }
+       }
+       
+       # Make sure log id was determined and is valid
+       if (!$request_log_id) {
+               notify($ERRORS{'WARNING'}, 0, "log id could not be determined");
+               return;
+       }
+       elsif ($request_log_id !~ /^\d+$/) {
+               notify($ERRORS{'WARNING'}, 0, "log id is not valid: 
$request_log_id");
+               return;
+       }
+       
+       # Construct a select statement 
+       my $sql_select_statement = "
+       SELECT
+       *
+       FROM
+       log
+       LEFT JOIN sublog ON sublog.logid = log.id
+       WHERE
+       log.id = $request_log_id
+       ";
+       
+       # Call database_select() to execute the select statement and make sure 
1 row was returned
+       my @select_rows = VCL::utils::database_select($sql_select_statement);
+       if (!scalar @select_rows == 1) {
+               notify($ERRORS{'WARNING'}, 0, "select statement returned " . 
scalar @select_rows . " rows:\n" . join("\n", $sql_select_statement));
+               return;
+       }
+       
+       # $select_rows[0] is a hash reference, the keys are the column names
+       # Loop through the column names and add the data to $self->request_data
+       my $row = $select_rows[0];
+       
+       my %data_hash;
+       foreach my $column_name (sort keys(%{$row})) {
+               # Get the data value for the column
+               my $data_value = $row->{$column_name};
+               $self->request_data->{log}{$column_name} = $data_value if 
!defined($self->request_data->{log}{$column_name});
+       }
+       
+       notify($ERRORS{'DEBUG'}, 0, "retrieved log data for log id: 
$request_log_id");
+       return $self->request_data->{log};
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
+=head2 update_log_ending_DataStructure
+
+ Parameters  : string containing the log ending value
+ Returns     : true if successful, false if failed
+ Description : Updates the log.ending value in the database for the log ID
+               set for this reservation. Returns false if log ID is not
+                                       set. A string argument must be passed 
containing the new
+                                       log.ending value.
+                                       
+=cut
+
+sub update_log_ending_DataStructure {
+       my $self = shift;
+       my $request_log_ending = shift;
+       
+       # Check if subroutine was called as an object method
+       if (!ref($self) =~ /DataStructure/) {
+               notify($ERRORS{'WARNING'}, 0, "subroutine must be called as an 
object method");
+               return;
+       }
+       
+       # Make sure log ending value was passed
+       if (!$request_log_ending) {
+               notify($ERRORS{'WARNING'}, 0, "log ending value argument was 
not passed");
+               return;
+       }
+       
+       # Get the log id
+       my $request_log_id = $self->get_request_log_id();
+       if (!$request_log_id) {
+               notify($ERRORS{'WARNING'}, 0, "request log id could not be 
retrieved");
+               return;
+       }
+       
+       # Get the request state name
+       my $request_state_name = $self->get_request_state_name();
+       if (!$request_state_name) {
+               notify($ERRORS{'WARNING'}, 0, "request state name could not be 
retrieved");
+               return;
+       }
+       
+       # Get the image id
+       my $image_id = $self->get_image_id();
+       if (!$image_id) {
+               notify($ERRORS{'WARNING'}, 0, "image id could not be 
retrieved");
+               return;
+       }
+       
+       # Get the image name
+       my $image_name = $self->get_image_name();
+       if (!$image_name) {
+               notify($ERRORS{'WARNING'}, 0, "image name could not be 
retrieved");
+               return;
+       }
+       
+       # Get the imagerevision production flag
+       my $imagerevision_production = $self->get_imagerevision_production();
+       if ($imagerevision_production !~ /^(0|1)$/) {
+               notify($ERRORS{'WARNING'}, 0, "imagerevision production flag 
could not be retrieved");
+               return;
+       }
+       
+       # Construct a select statement to retrieve the resource group names 
this image belongs to
+       my $select_image_groups_statement = "
+       SELECT DISTINCT
+       resourcegroup.name
+       FROM
+       image,
+       resource,
+       resourcetype,
+       resourcegroup,
+       resourcegroupmembers
+       WHERE
+       image.id = $image_id AND
+       resource.subid = image.id AND resource.resourcetypeid = 13 AND
+       resourcegroupmembers.resourceid = resource.id AND
+       resourcegroup.id = resourcegroupmembers.resourcegroupid
+       ";
+       
+       # Call database_select() to execute the select statement
+       my @image_group_rows = 
VCL::utils::database_select($select_image_groups_statement);
+       if (!scalar @image_group_rows == 1) {
+               notify($ERRORS{'WARNING'}, 0, "unable to retrieve image group 
names for image $image_name");
+               return;
+       }
+       
+       # Assemble an array from the select return array
+       my @image_group_names;
+       for my $image_group_row (@image_group_rows) {
+               my $image_group_name = $image_group_row->{name};
+               push @image_group_names, $image_group_name;
+       }
+       notify($ERRORS{'DEBUG'}, 0, "retrieved groups image $image_name belongs 
to:\n" . join("\n", @image_group_names));
+       
+       
+       # Make sure the requested log ending makes sense
+       
+       # Don't set ending to 'failed' if image only belongs to newimages-* 
group
+       if ($request_log_ending eq 'failed' && scalar @image_group_names == 1 
&& $image_group_names[0] =~ /^newimages-.*/i) {
+               notify($ERRORS{'WARNING'}, 0, "log ending should not be set to 
'$request_log_ending' because image only belongs to $image_group_names[0] 
group, changing to 'failedtest'");
+               $request_log_ending = 'failedtest';
+       }
+       
+       # Don't set ending to 'failed' if not a state the end user sees
+       if ($request_log_ending eq 'failed' && $request_state_name =~ 
/^(reload|to.*|makeproduction|.*hpc.*|image)$/) {
+               notify($ERRORS{'WARNING'}, 0, "log ending should not be set to 
'$request_log_ending' because request state is $request_state_name, changing to 
'failedtest'");
+               $request_log_ending = 'failedtest';
+       }
+       
+       # Don't set ending to 'failed' if imagerevision.production = 0
+       if ($request_log_ending eq 'failed' && !$imagerevision_production) {
+               notify($ERRORS{'WARNING'}, 0, "log ending should not be set to 
'$request_log_ending' because imagerevision.production = 0, changing to 
'failedtest'");
+               $request_log_ending = 'failedtest';
+       }
+       
+       
+       # Construct the update statement 
+       my $sql_update_statement = "
+       UPDATE
+       log
+       SET
+       log.ending = \'$request_log_ending\',
+       log.finalend = NOW()
+       WHERE
+       log.id = $request_log_id
+       ";
+       
+       # Execute the update statement
+       if (database_execute($sql_update_statement)) {
+               notify($ERRORS{'OK'}, 0, "executed update statement to set log 
ending to $request_log_ending for log id: $request_log_id");
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "failed to execute update 
statement to set log ending to $request_log_ending for log id: 
$request_log_id");
+               return;
+       }
+       
+       # Check the actual ending value in the database, SQL update returns 1 
even if 0 rows were affected
+       # Construct a select statement 
+       my $sql_select_statement = "
+       SELECT
+       log.ending,
+       log.finalend
+       FROM
+       log
+       WHERE
+       log.id = $request_log_id
+       ";
+       
+       # Call database_select() to execute the select statement and make sure 
1 row was returned
+       my @select_rows = VCL::utils::database_select($sql_select_statement);
+       if (!scalar @select_rows == 1) {
+               notify($ERRORS{'WARNING'}, 0, "unable to verify log ending 
value, select statement returned " . scalar @select_rows . " rows:\n" . 
join("\n", $sql_select_statement));
+               return;
+       }
+       
+       # $select_rows[0] is a hash reference, the keys are the column names
+       my $log_ending = $select_rows[0]->{ending};
+       
+       # Compare the ending value in the database to the argument
+       if ($log_ending && $log_ending eq $request_log_ending) {
+               notify($ERRORS{'DEBUG'}, 0, "verified log ending was set to 
'$request_log_ending' for log id: $request_log_id");
+       }
+       else {
+               notify($ERRORS{'WARNING'}, 0, "log ending in database 
('$log_ending') does not match requested value ('$request_log_ending') for log 
id: $request_log_id");
+               return;
+       }
+
+       return 1;
+}
+
+#/////////////////////////////////////////////////////////////////////////////
+
 1;
 __END__
 


Reply via email to