webgui/lib/WebGUI/Operation/Spectre.pm
Graham Knop 9ed284beec use UTF8 JSON encoding and decoding universally
fixed: Import/Export of packages with international text is broken
2008-04-01 14:42:20 +00:00

223 lines
6.6 KiB
Perl

package WebGUI::Operation::Spectre;
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2008 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 JSON;
use POE::Component::IKC::ClientLite;
use WebGUI::Utility;
use WebGUI::Workflow::Cron;
use WebGUI::Workflow::Instance;
=head1 NAME
Package WebGUI::Operation::Spectre
=head1 DESCRIPTION
Operations for Spectre.
=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("groupIdAdminSpectre") );
}
#----------------------------------------------------------------------------
=head2 getASpectre ( [$session] )
Get a connection to spectre. Encapsulated here so outside code can call
something that's carefully encapsulated.
=head3 $session
A WebGUI session variable so getASpectre can access information in
the config file.
=cut
sub getASpectre {
my $session = shift;
my $remote = create_ikc_client(
port=>$session->config->get("spectrePort"),
ip=>$session->config->get("spectreIp"),
name=>rand(100000),
timeout=>10
);
return $remote;
}
#-------------------------------------------------------------------
=head2 www_spectreGetSiteData ( )
Checks to ensure the requestor is who we think it is, and then returns a JSON string with worklfow and cron data. We do it in one payload for efficiency.
=cut
sub www_spectreGetSiteData {
my $session = shift;
$session->http->setMimeType("text/json");
$session->http->setCacheControl("none");
my %siteData = ();
my $subnets = $session->config->get("spectreSubnets");
if (!defined $subnets) {
$subnets = [];
}
if (!isInSubnet($session->env->getIp, $subnets)) {
$session->errorHandler->security("Tried to make a Spectre workflow data load request, but we're only allowed to accept requests from "
.join(",",@{$subnets}).".");
}
else {
my $sitename = $session->config->get("sitename")->[0];
my $gateway = $session->config->get("gateway");
my $cookieName = $session->config->getCookieName;
my @instances = ();
foreach my $instance (@{WebGUI::Workflow::Instance->getAllInstances($session)}) {
next unless $instance->getWorkflow->get("enabled");
push(@instances, {
instanceId => $instance->getId,
priority => $instance->get("priority"),
cookieName => $cookieName,
gateway => $gateway,
sitename => $sitename,
});
}
$siteData{workflow} = \@instances;
my @schedules = ();
foreach my $task (@{WebGUI::Workflow::Cron->getAllTasks($session)}) {
next unless $task->get("enabled");
push(@schedules, {
taskId => $task->getId,
cookieName => $cookieName,
gateway => $gateway,
sitename => $sitename,
minuteOfHour => $task->get('minuteOfHour'),
hourOfDay => $task->get('hourOfDay'),
dayOfMonth => $task->get('dayOfMonth'),
monthOfYear => $task->get('monthOfYear'),
dayOfWeek => $task->get('dayOfWeek'),
runOnce => $task->get('runOnce'),
});
}
$siteData{cron} = \@schedules;
}
return JSON::encode_json(\%siteData);
}
#-------------------------------------------------------------------
=head2 www_spectreStatus ( )
Show information about Spectre's current workload.
=cut
sub www_spectreStatus {
my $session = shift;
return $session->privilege->adminOnly unless canView($session);
# start to prepare the display
my $ac = WebGUI::AdminConsole->new($session, 'spectre');
my $i18n = WebGUI::International->new($session, 'Spectre');
$session->http->setCacheControl("none");
my $remote = create_ikc_client(
port=>$session->config->get("spectrePort"),
ip=>$session->config->get("spectreIp"),
name=>rand(100000),
timeout=>10
);
if (!$remote) {
return $ac->render($i18n->get('not running'), $i18n->get('spectre'));
}
my $sitename = $session->config()->get('sitename')->[0];
my $workflowResult = $remote->post_respond('workflow/getJsonStatus',$sitename);
if (!$workflowResult) {
$remote->disconnect();
return $ac->render($i18n->get('workflow status error'), $i18n->get('spectre'));
}
my $cronResult = $remote->post_respond('cron/getJsonStatus',$sitename);
if (! defined $cronResult) {
$remote->disconnect();
return $ac->render($i18n->get('cron status error'), $i18n->get('spectre'));
}
my %data = (
workflow => decode_json($workflowResult),
cron => decode_json($cronResult),
);
my $workflowCount = @{ $data{workflow}{Suspended} } + @{ $data{workflow}{Waiting} } + @{ $data{workflow}{Running} };
my $workflowUrl = $session->url->page('op=showRunningWorkflows');
my $cronCount = keys %{ $data{cron} };
my $cronUrl = $session->url->page('op=manageCron');
my $output = $i18n->get('running').'<br/>';
$output .= sprintf $i18n->get('workflow header'), $workflowUrl, $workflowCount;
$output .= sprintf $i18n->get('cron header'), $cronUrl, $cronCount;
return $ac->render($output, $i18n->get('spectre'));
}
#-------------------------------------------------------------------
=head2 www_spectreTest ( )
Spectre executes this function to see if WebGUI connectivity is working.
=cut
sub www_spectreTest {
my $session = shift;
$session->http->setMimeType("text/plain");
$session->http->setCacheControl("none");
my $subnets = $session->config->get("spectreSubnets");
if (!defined $subnets) {
$subnets = [];
}
unless (isInSubnet($session->env->getIp, $subnets)) {
$session->errorHandler->security("Tried to make a Spectre workflow runner request, but we're only allowed to accept requests from ".join(",",@{$subnets}).".");
return "subnet";
}
my $remote = create_ikc_client(
port=>$session->config->get("spectrePort"),
ip=>$session->config->get("spectreIp"),
name=>rand(100000),
timeout=>10
);
# Can't perform this test until I get smarter. =)
return "spectre" unless defined $remote;
my $result = $remote->post_respond('admin/ping');
$remote->disconnect;
return "spectre" unless defined $result;
return "success";
}
1;