package WebGUI::Operation::Cron; #------------------------------------------------------------------- # WebGUI is Copyright 2001-2009 Plain Black Corporation. #------------------------------------------------------------------- # Please read the legal notices (docs/legal.txt) and the license # (docs/license.txt) that came with this distribution before using # this software. #------------------------------------------------------------------- # http://www.plainblack.com info@plainblack.com #------------------------------------------------------------------- use strict; use Tie::IxHash; use WebGUI::AdminConsole; use WebGUI::HTMLForm; use WebGUI::International; use WebGUI::Workflow::Cron; use WebGUI::Workflow::Instance; use WebGUI::Utility; =head1 NAME Package WebGUI::Operations::Cron =head1 DESCRIPTION Operation handler for managing scheduler activities. =cut #---------------------------------------------------------------------------- =head2 canView ( session [, user] ) Returns true if the user can administrate this operation. user defaults to the current user. =cut sub canView { my $session = shift; my $user = shift || $session->user; return $user->isInGroup( $session->setting->get("groupIdAdminCron") ); } #------------------------------------------------------------------- =head2 www_deleteCronJob ( ) Deletes a cron job. =cut sub www_deleteCronJob { my $session = shift; return $session->privilege->adminOnly unless canView($session); my $cron = WebGUI::Workflow::Cron->new($session, $session->form->get("id")); $cron->delete if defined $cron; return www_manageCron($session); } #------------------------------------------------------------------- =head2 www_editCronJob ( ) Displays an edit form for a cron job. =cut sub www_editCronJob { my $session = shift; return $session->privilege->adminOnly unless canView($session); my $i18n = WebGUI::International->new($session, "Workflow_Cron"); my $cron = WebGUI::Workflow::Cron->new($session, $session->form->get("id")); my $f = WebGUI::HTMLForm->new($session); $f->submit; $f->hidden( name=>"op", value=>"editCronJobSave" ); $f->hidden( name=>"id", defaultValue=>"new", value=>$session->form->get("id"), ); $f->readOnly( label=>$i18n->get("id"), defaultValue=>"new", value=>$session->form->get("id"), ); my $value = $cron->get("title") if defined $cron; $f->text( name=>"title", value=>$value, label=>$i18n->get("title"), hoverHelp=>$i18n->get("title help") ); $value = $cron->get("enabled") if defined $cron; $f->yesNo( name=>"enabled", value=>$value, defaultValue=>0, label=>$i18n->get("is enabled"), hoverHelp=>$i18n->get("is enabled help") ); $value = $cron->get("runOnce") if defined $cron; $f->yesNo( name=>"runOnce", value=>$value, defaultValue=>0, label=>$i18n->get("run once"), hoverHelp=>$i18n->get("run once help") ); $value = $cron->get("workflowId") if defined $cron; my $type = "None"; if (defined $cron && $cron->get("className")) { $type = $cron->get("className"); } $f->workflow( name=>"workflowId", value=>$value, type=>$type, label=>$i18n->get("workflow"), hoverHelp=>$i18n->get("workflow help") ); my %priorities = (); tie %priorities, 'Tie::IxHash'; %priorities = (1=>$i18n->get("high"), 2=>$i18n->get("medium"), 3=>$i18n->get("low")); $value = $cron->get("priority") if defined $cron; $f->radioList( name=>"priority", vertical=>1, value=>$value, defaultValue=>2, options=>\%priorities, label=>$i18n->get("priority"), hoverHelp=>$i18n->get("priority help") ); $value = $cron->get("minuteOfHour") if defined $cron; $f->text( name=>"minuteOfHour", value=>$value, defaultValue=>0, label=>$i18n->get("minute of hour"), hoverHelp=>$i18n->get("minute of hour help") ); $value = $cron->get("hourOfDay") if defined $cron; $f->text( name=>"hourOfDay", value=>$value, defaultValue=>"*", label=>$i18n->get("hour of day"), hoverHelp=>$i18n->get("hour of day help") ); $value = $cron->get("dayOfMonth") if defined $cron; $f->text( name=>"dayOfMonth", value=>$value, defaultValue=>"*", label=>$i18n->get("day of month"), hoverHelp=>$i18n->get("day of month help") ); $value = $cron->get("monthOfYear") if defined $cron; $f->text( name=>"monthOfYear", value=>$value, defaultValue=>"*", label=>$i18n->get("month of year"), hoverHelp=>$i18n->get("month of year help") ); $value = $cron->get("dayOfWeek") if defined $cron; $f->text( name=>"dayOfWeek", value=>$value, defaultValue=>"*", label=>$i18n->get("day of week"), hoverHelp=>$i18n->get("day of week help") ); $f->submit; my $ac = WebGUI::AdminConsole->new($session,"cron"); $ac->addSubmenuItem($session->url->page("op=editCronJob"), $i18n->get("add a new task")); $ac->addSubmenuItem($session->url->page("op=manageCron"), $i18n->get("manage tasks")); return $ac->render($f->print); } #------------------------------------------------------------------- =head2 www_editCronJobSave ( ) Saves the results of www_editCronJob() =cut sub www_editCronJobSave { my $session = shift; return $session->privilege->adminOnly unless canView($session); if ($session->form->get("id") eq "new") { WebGUI::Workflow::Cron->create($session,{ monthOfYear=>$session->form->get("monthOfYear"), dayOfMonth=>$session->form->get("dayOfMonth"), minuteOfHour=>$session->form->get("minuteOfHour"), hourOfDay=>$session->form->get("hourOfDay"), dayOfWeek=>$session->form->get("dayOfWeek"), enabled=>$session->form->get("enabled","yesNo"), runOnce=>$session->form->get("runOnce","yesNo"), priority=>$session->form->get("priority","radioList"), workflowId=>$session->form->get("workflowId","workflow"), title=>$session->form->get("title"), }); } else { my $cron = WebGUI::Workflow::Cron->new($session, $session->form->get("id")); $cron->set({ monthOfYear=>$session->form->get("monthOfYear"), dayOfMonth=>$session->form->get("dayOfMonth"), minuteOfHour=>$session->form->get("minuteOfHour"), hourOfDay=>$session->form->get("hourOfDay"), dayOfWeek=>$session->form->get("dayOfWeek"), enabled=>$session->form->get("enabled","yesNo"), runOnce=>$session->form->get("runOnce","yesNo"), priority=>$session->form->get("priority","radioList"), workflowId=>$session->form->get("workflowId","workflow"), title=>$session->form->get("title"), }); } return www_manageCron($session); } #------------------------------------------------------------------- =head2 www_manageCron ( ) Display a list of the scheduler activities. =cut sub www_manageCron { my $session = shift; return $session->privilege->adminOnly unless canView($session); my $i18n = WebGUI::International->new($session, "Workflow_Cron"); my $output = ''; my $rs = $session->db->read("select taskId, title, concat(minuteOfHour, ' ', hourOfDay, ' ', dayOfMonth, ' ', monthOfYear, ' ', dayOfWeek), enabled from WorkflowSchedule"); while (my ($id, $title, $schedule, $enabled) = $rs->array) { $output .= '"; $output .= ''; $output .= "\n"; } $output .= '
' .$session->icon->delete("op=deleteCronJob;id=".$id, undef, $i18n->get("are you sure you wish to delete this scheduled task")) .$session->icon->edit("op=editCronJob;id=".$id) .''.$title.''.$schedule.'' .($enabled ? $i18n->get("enabled") : $i18n->get("disabled")) ."'.$i18n->get("run","Workflow").'
'; my $ac = WebGUI::AdminConsole->new($session,"cron"); $ac->addSubmenuItem($session->url->page("op=editCronJob"), $i18n->get("add a new task")); return $ac->render($output); } #------------------------------------------------------------------- =head2 www_runCronJob ( ) Checks to ensure the requestor is who we think it is, and then executes a cron job and returns the results. =cut sub www_runCronJob { my $session = shift; $session->http->setMimeType("text/plain"); $session->http->setCacheControl("none"); unless (isInSubnet($session->env->getIp, $session->config->get("spectreSubnets")) || canView($session)) { $session->errorHandler->security("make a Spectre cron job runner request, but we're only allowed to accept requests from ".join(",",@{$session->config->get("spectreSubnets")})."."); return "error"; } my $taskId = $session->form->param("taskId"); if ($taskId) { # Try to instantiate the task my $task = WebGUI::Workflow::Cron->new($session, $taskId); return "done" unless (defined $task); # Make a new workflow instance my $instance = WebGUI::Workflow::Instance->create($session, { workflowId => $task->get("workflowId"), className => $task->get("className"), methodName => $task->get("methodName"), parameters => $task->get("parameters"), priority => $task->get("priority"), }); if ( !$instance ) { if ($session->stow->get('singletonWorkflowClash')) { $session->errorHandler->warn( "Could not create workflow instance for workflowId '" . $task->get( "workflowId" ) . "' from taskId '".$taskId."': It is a singleton workflow and is still running from the last invocation." ); return "done"; } $session->errorHandler->error( "Could not create workflow instance for workflowId '" . $task->get( "workflowId" ) . "' from taskId '".$taskId."': The result was undefined" ); return "done"; } # Run the instance my $error = $instance->start( 1 ); if ($error) { ##Unable to communicate with spectre. Delete this instance to it does not get stuck. $session->log->error("Unable to communicate with spectre: $error about taskId: $taskId. Deleting instanceId: ". $instance->getId); $instance->delete(); return "error"; } $task->delete( 1 ) if ( $task->get("runOnce") ); return "done"; } $session->errorHandler->warn("No task ID passed to cron job runner."); return "error"; } 1;