view release on metacpan or search on metacpan
transport with users, packages and other pertinent information.
The Agent will log in, join chatrooms if in the user list,
and wait for further commands from authorized users or in a chatroom.
Test script:
A test script is written, Agent::TCLI::Testee, that loads up a Test Transport,
other necessary transports, necessary local packages, and testees.
Using testees, one creates tests ala Test::More with Agent controlling
versions of ok, is_ , and like_ tests.
These will run asynchronously after the testing starts. One must be conscious
of the asynchronous nature of the test flow.
It is necessary to call the test_master->run at the end of the test to ensure
that all tests have completed.
COPYRIGHT AND LICENCE
Copyright (C) 2007, Alcatel-Lucent
This library is free software; you can redistribute it and/or modify
bin/agent_tail.pl view on Meta::CPAN
Print a brief help message and exit.
=item B<man>
Print this command's manual page and exit.
=back
=head1 DESCRIPTION
B<agent_tail> will start a TCLI Agent running on the XMPP Transport
with the Tail and XMPP packages loaded.
Use B<agent_tail> as is or as the basis for creating Agents with different
functionaity.
=head1 SEE ALSO
L<Agent::TCLI>
=head1 AUTHOR
bin/agent_tail.pl view on Meta::CPAN
'verbose' => \$verbose, # Verbose sets level or warnings
'control_options' => {
'packages' => \@packages,
},
);
print "Starting ".$alias unless $verbose;
# Required to start the Agent
POE::Kernel->run();
print" FINISHED";
exit;
lib/Agent/TCLI.pm view on Meta::CPAN
through additional modules in collections called packages.
TCLI attempts to make writing these
modules easier by providing Base classes that offer much of the
needed functionality to support the standardized, easy to learn human
interface. The goal is to allow users to add new functionality without
having then spend a lot of time learning the particular syntax of a
new tool.
=head1 GETTING STARTED
The quickest way to start running an agent is to run the provided Tail Agent:
tail_agent user=<user> password=<example> domain=<example.com>
One must fist have created a Jabber/XMPP account for the agent to log in to.
One can then log in with a Jabber client using the same user ID and password
and communicate with the Agent. The Agnet will be logged in using the
resource 'tcli'. Jabber clients vary in how to start a chat with onself
at a different resource, so please see your Jabber client documentation
for details.
=head1 COMPONENTS
The following modules make up the core of the TCLI system.
=head2 Agent::TCLI::Control
The L<Agent::TCLI::Control> is the key broker between the Transports and the
lib/Agent/TCLI/Command.pm view on Meta::CPAN
:All('manual');
=item command
A reference to the sub routine that will execute the command
or the name of the package session that will run the command.
=cut
my @command :Field :All('command');
=item start
Deprecated: A reference to a subroutine that is necessary to intialize the command at control startup.
B<start> will only accept CODE type values.
=cut
my @start :Field :All('start')
:Type('CODE');
=item stop
Deprecated: A code reference for shutting down anything as the control shuts down.
B<stop> will only accept CODE type values.
=cut
my @stop :Field :All('stop')
:Type('CODE');
=item handler
lib/Agent/TCLI/Command.pm view on Meta::CPAN
#sub RawCommand {
# my $self = shift;
## my %cmd = validate( @_, {
## help_text => { type => Params::Validate::SCALAR }, #required
## usage => { type => Params::Validate::SCALAR }, #required
## topic => { optional => 1, type => Params::Validate::SCALAR },
## name => { type => Params::Validate::SCALAR }, #required
## command => { type => ( Params::Validate::SCALAR | Params::Validate::CODEREF ) }, #required
## context => { optional => 1, type => Params::Validate::ARRAYREF },
## style => { optional => 1, type => Params::Validate::SCALAR },
## start => { optional => 1, type => Params::Validate::CODEREF },
## handler => { optional => 1, type => Params::Validate::SCALAR },
## stop => { optional => 1, type => Params::Validate::CODEREF },
## } );
#
# my %cmdhash = (
# 'name' => $name[$$self],
# 'help' => $help[$$self],
# 'usage' => $usage[$$self],
# 'command' => $command[$$self],
# );
# $cmdhash{'topic'} = $topic[$$self] if (defined($topic[$$self]));
# $cmdhash{'contexts'} = $contexts[$$self] if (defined($contexts[$$self]));
# $cmdhash{'call_style'} = $call_style[$$self] if (defined($call_style[$$self]));
# $cmdhash{'handler'} = $handler[$$self] if (defined($handler[$$self]));
# $cmdhash{'start'} = $start[$$self] if (defined($start[$$self]));
# $cmdhash{'stop'} = $stop[$$self] if (defined($stop[$$self]));
#
# return ( \%cmdhash );
#}
=item GetoptLucid( $kernel, $request)
Returns an option hash keyed on parameter after the arguments have bee parsed
by Getopt::Lucid. Will respond itself if there is an error and return nothing.
lib/Agent/TCLI/Control.pm view on Meta::CPAN
=item registered_commands
The collection of registered_commands in the control library. Commands may
not be set, but must added with the register method.
=cut
my @registered_commands :Field :Get('registered_commands');
my @starts :Field :Get('starts');
my @stops :Field :Get('stops');
my @handlers :Field :Get('handlers');
my @start_time :Field
:Get('start_time');
my @user :Field :All('user')
:Type('Agent::TCLI::User');
my @packages :Field :All('packages');
#my @alias :Field :All('alias');
=item auth
lib/Agent/TCLI/Control.pm view on Meta::CPAN
=over
=cut
sub _preinit :Preinit {
my ($self,$args) = @_;
$args->{'session'} = POE::Session->create(
object_states => [
$self => [qw(
_start
_stop
_shutdown
_default
ControlAddState
control_presence
AsYouWished
ChangeContext
Execute
lib/Agent/TCLI/Control.pm view on Meta::CPAN
# if available, register requested command packages
$self->Verbose( "init: Registering user packages \n" );
if ( defined($packages[$$self] ) )
{
my $txt;
foreach my $package (@{ $packages[$$self] })
{
my $txt = $self->RegisterPackage($package);
croak ($txt) if ($txt); # Load fail on start MUST die.
}
} # end if packages
# Register user commands, if requested #{{{
# $self->Verbose( "init: Registering user commands \n" );
#
# if( ref( $commands[$$self] ) =~ /ARRAY/i ) {
#
# foreach my $cmd (@{ $commands[$$self] }) {
# if ( ref($cmd) eq 'HASH') {
lib/Agent/TCLI/Control.pm view on Meta::CPAN
my $self = shift;
$self->Verbose("Register: params",4,@_);
my %cmd = validate( @_, {
help => { type => Params::Validate::SCALAR }, #required
usage => { type => Params::Validate::SCALAR }, #required
topic => { optional => 1, type => Params::Validate::SCALAR },
name => { type => Params::Validate::SCALAR }, #required
command => { type => ( Params::Validate::SCALAR | Params::Validate::CODEREF ) }, #required
contexts => { optional => 1, type => Params::Validate::HASHREF },
call_style => { optional => 1, type => Params::Validate::SCALAR },
# start => { optional => 1, type => Params::Validate::CODEREF },
handler => { optional => 1, type => Params::Validate::SCALAR },
# stop => { optional => 1, type => Params::Validate::CODEREF },
} );
# Set up a default contexts if one not provided.
$cmd{'contexts'} = { 'ROOT' => $cmd{'name'} } unless (defined ( $cmd{'contexts'}) );
$self->Verbose("Register: name ".$cmd{'name'} );
$self->RegisterContexts(\%cmd);
# # Don't want these in loop, since they only should get added once.
# push ( @{ $starts[$$self] }, \%cmd ) if ( defined ( $cmd{'start'} ) );
# push ( @{ $handlers[$$self] }, \%cmd ) if ( defined ( $cmd{'handler'} ) );
# push ( @{ $stops[$$self] }, \%cmd ) if ( defined ( $cmd{'stop'} ) );
$self->Verbose("Register: commands \n",5,$registered_commands[$$self]);
return 1;
}
=item RegisterContexts
lib/Agent/TCLI/Control.pm view on Meta::CPAN
}
else
{
$self->Verbose( "RegisterPackage: Bad package $package->dump(1) ",0 );
$self->Verbose( "RegisterPackage: Bad package commands ref(".ref($commands).") dump",0,$commands );
$txt = "Bad package $package";
}
return $txt;
}
=item _start
POE event to load up any initialization routines for commands.
=cut
sub _start {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
if (!defined( $self->id ))
{
$self->Verbose("_start: OIO not done re-starting");
$kernel->yield('_start');
return;
}
$kernel->alias_set("$id[$$self]");
$self->Verbose("_start: Starting commands start routines \n");
foreach my $startcmd ( @{ $starts[$$self] } ) {
if ( ref($startcmd) eq 'HASH' )
{
if (defined ($startcmd->{'start'})) {
$self->Verbose("_start:\trunning ".$startcmd->{'name'}." 's start \n",2) ;
eval { $startcmd->{'start'}( kernel => $kernel,
object => $self,
session => $session,
) }
}
}
elsif ( ref($startcmd) =~ /Agent::TCLI::Command/ )
{
$self->Verbose("_start:\trunning ".$startcmd->name()." 's start \n",2) ;
# TODO some error checking here maybe :)
$startcmd->start( { kernel => $kernel,
object => $self,
session => $session,
} );
}
}
# Handlers are events to send the request to. The result will be returned
# to AsYouWished.
# The handler is the name of the event, and the command is the session that
# will handle the event.
# Often the handler name will not be the actual command name.
# TODO, this isn't doing anything right now. Should it? Or are we doing it in the
# _starts session creation....
$self->Verbose("_start: Insert command handler states \n");
foreach my $command ( @{ $handlers[$$self] } ) {
# if the command is not defined, the handler is assumed to be pre-loaded
if ( ref($command->{'command'}) =~ /CODE/ ) {
$self->Verbose("_start:\tregistering ".$command->{'name'}." 's handler $command->{'handler'} \n", 2 );
$kernel->state( $command->{'handler'} , $command->{'command'} );
}
}
# unless ($heap->{no_std_tie}) {
# $self->Verbose "tie STDOUT and STDERR \n" if VERBOSE;
# tie *STDOUT, __PACKAGE__."::Output", 'stdout', \&jabber_send_msg;
# tie *STDERR, __PACKAGE__."::Output", 'stderr', \&jabber_send_msg;
# }
#
# if ($heap->{ties}) {
# foreach (@{$heap->{ties}}) {
# $self->Verbose "tie $_ \n" if VERBOSE;
# tie *$_, __PACKAGE__."::Output", $_, \&jabber_send_msg;
# }
# }
if( $self->session )
{
$self->set(\@start_time, time() );
$self->Verbose( "_started: up at ".$self->start_time.
" _start completed. \n\n");
}
} # End sub _start
=item stop
Poe state that is mostly just a placeholder.
=cut
sub _stop {
my ($kernel, $self, $session) = @_[KERNEL, OBJECT, SESSION];
$self->Verbose("Stopping ".$self->id );
lib/Agent/TCLI/Control.pm view on Meta::CPAN
sub general {
my ($kernel, $self, $sender, $request,) =
@_[KERNEL, OBJECT, SENDER, ARG0,];
$self->Verbose("general: context(".$self->print_context.")");
my $command = $request->command->[0];
$self->Verbose("general: command(".$command.") args[".
$request->print_args."] input(".$request->input.")", 3);
my $txt;
my $time = localtime($start_time[$$self]);
if ( $command eq 'context')
{
$txt = "Context: ".$self->print_context;
}
elsif ( $command eq 'echo' )
{
$txt = "I heard '".$request->input."' in context ".
$self->print_context." from ".$user[$$self]->get_name();
}
lib/Agent/TCLI/Package/Base.pm view on Meta::CPAN
=over
=cut
sub _preinit :Preinit {
my ($self,$args) = @_;
$args->{'session'} = POE::Session->create(
object_states => [
$self => [qw(
_start
_stop
_shutdown
_default
establish_context
settings
show
)],
],
)
unless defined( $args->{'session'} );
}
# This POE event handler is called when POE starts up a Package.
# The B<_start> method is :Cumulative within OIO. Ideally, most command packages
# could use this Base _start method without implementing
# their own. However there seems to be a race condition between the POE
# initialization and the OIO object initialization. Until this is debugged
# one will probably have to have this _start method in every package.
sub _start :Cumulative {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
# are we up before OIO has finished initializing object?
if (!defined( $self->name ))
{
$self->Verbose("_start: OIO not done re-starting");
$kernel->yield('_start');
# $kernel->delay('_start', 1 );
return;
}
$self->Verbose("_start: ".$self->name()." starting");
# There is only one command object per TCLI
$kernel->alias_set($self->name);
}
# This POE event handler is used to initiate a shutdown of the Control.
sub _shutdown :Cumulative {
my ($kernel, $self,) =
@_[KERNEL, OBJECT,];
$self->Verbose("_shutdown:base ".$self->name." shutting down");
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
}
sub _preinit :Preinit {
my ($self,$args) = @_;
$args->{'name'} = 'tcli_tail';
$args->{'session'} = POE::Session->create(
object_states => [
$self => [qw(
_start
_stop
_shutdown
_default
_child
clear
establish_context
file
log
show
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
name: interval
help: Seconds to wait between checks.
manual: >
Seconds to wait between checks.
type: Param
---
Agent::TCLI::Parameter:
name: seek
help: Seek forward byte count.
manual: >
The Seek parameter tells Tail how far from the start of the file to start
reading. Its value is specified in bytes, and values greater than the
file's current size will quietly cause Tail to start from the file's end.
A Seek parameter of 0 starts FollowTail at the beginning of the file.
A negative Seek parameter emulates SeekBack: it seeks backwards from
the end of the file.
Seek and SeekBack are mutually exclusive. If Seek and SeekBack are not
specified, Tail seeks 4096 bytes back from the end of the file
and discards everything until the end of the file. This helps ensure
that Tail returns only complete records.
type: Param
---
Agent::TCLI::Parameter:
name: seekback
help: Seek backwards byte count.
manual: >
The SeekBack parameter tells Tail how far back from the end of the file
to start reading. Its value is specified in bytes, and values greater
than the file's current size will quietly cause Tail to start from
the file's beginning.
A SeekBack parameter of 0 starts Tail at the end of the file.
It's recommended to omit Seek and SeekBack to start from the end of a file.
A negative SeekBack parameter emulates Seek: it seeks forwards from
the start of the file.
type: Param
---
Agent::TCLI::Parameter:
name: name
help: The name of the test.
manual: >
The name is purely cosmetic and will be returned with the test results
simliarly to the way Test::Simple operates. This might be useful
when reporting results to a group chat or log.
type: Param
lib/Agent/TCLI/Package/Tail.pm view on Meta::CPAN
=cut
sub _shutdown :Cumulative {
my ($kernel, $self,) =
@_[KERNEL, OBJECT,];
$self->Verbose("_shutdown:tail ".$self->name." shutting down");
return;
}
=item _start
This POE event handler is called when POE starts up a Package.
The B<_start> method is :Cumulative within OIO.
=cut
sub _start {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
$self->Verbose("_start: Starting test_tail ");
# are we up before OIO has finished initializing object?
if (!defined( $self->name ))
{
$kernel->yield('_start');
return;
}
# There is only one command object per TCLI
$kernel->alias_set($self->name);
$kernel->delay('PruneLineCache',10);
$kernel->delay('Activate', $self->interval , 0 );
return("_start ".$self->name);
}
1;
#__END__
=back
=head3 INHERITED METHODS
This module is an Object::InsideOut object that inherits from
lib/Agent/TCLI/Package/UnixBase.pm view on Meta::CPAN
=head1 DESCRIPTION
Base class for Packages needing to run other Unix programs. It provides methods
to asnychronously call Unix programs using POW::Wheel::Run through
POE::Component::Child. This base class comes with simple
event handlers to accept the output and/or errors returned from the wheel.
Typically, one may want their subclass to replace the stdout method
with one that does more processing of the responses. One should use the
methods here as a starting point in such cases.
Commands run through these methods are run in their own processes asychonously.
Other Agent processing continues while the results of the commands are
captured and returned. Package authors need to ensure that their command
threads shut down or else they may exhaust system resources.
=head1 INTERFACE
=cut
lib/Agent/TCLI/Package/UnixBase.pm view on Meta::CPAN
# Standard class utils are inherited
=back
See Agent::TCLI::Package::Base for other attributes applicable to Packages.
=head2 METHODS
These simple methods may be used as is, or subclasses may use them as
starting point.
=over
=item RunWheelStart
This initializes the POE::Component::Child session. It may be called
from a Package's _start routine or the contents may be copied for further
modification.
=cut
sub RunWheelStart {
my $self = shift;
$self->child( POE::Component::Child->new(
alias => $self->name,
# debug => $self->verbose,
lib/Agent/TCLI/Package/XMPP.pm view on Meta::CPAN
=cut
sub _preinit :Preinit {
my ($self,$args) = @_;
$args->{'name'} = 'tcli_xmpp';
$args->{'session'} = POE::Session->create(
object_states => [
$self => [qw(
_start
_stop
_shutdown
_default
change
establish_context
peer
show
shutdown
)],
lib/Agent/TCLI/Package/XMPP.pm view on Meta::CPAN
This POE event handler executes the peer commands.
=cut
sub peer {
my ($kernel, $self, $sender, $request, ) =
@_[KERNEL, OBJECT, SENDER, ARG0, ];
# It seems that the proper way to handle removing users would be to delete
# the user's control and making sure that the user is authenticated before
# starting up a new control. There needs to be a remove control capability
# within a transport.
my $txt = '';
my $param;
my $command = $request->command->[0];
my $cmd = $self->commands->{'peer-'.$command};
# break down args
return unless ( $param = $cmd->Validate($kernel, $request, $self) );
lib/Agent/TCLI/Package/XMPP.pm view on Meta::CPAN
sub shutdown {
my ($kernel, $self, $sender, $request, ) =
@_[KERNEL, OBJECT, SENDER, ARG0, ];
$self->Verbose("shutdown: request ".$request->id );
$self->Verbose("shutdown: sending shutdown to transport_xmpp");
$request->Respond($kernel, "Shutting down transport_xmpp");
$kernel->post('transport_xmpp' => '_shutdown');
}
=item start
This POE event handler executes the start command. It is not exactly clear
when this would be useful currently, but we have a shutdown command and
balance must be maintained. Hopefully other transports will be available
in the future and this command might be more useful.
=back
=cut
sub start {
my ($kernel, $self, $sender, $request, ) =
@_[KERNEL, OBJECT, SENDER, ARG0, ];
$self->Verbose("start: request ".$request->id );
$self->Verbose("start: sending start to transport_xmpp");
$request->Respond($kernel, "Starting transport_xmpp");
$kernel->post('transport_xmpp' => '_start');
}
1;
#__END__
=head3 INHERITED METHODS
This module is an Object::InsideOut object that inherits from Agent::TCLI::Package::Base. It
inherits methods from both. Please refer to their documentation for more
lib/Agent/TCLI/Transport/Base.pm view on Meta::CPAN
B<controls> will only accept hash objects.
=cut
my @controls :Field
:All('controls')
:Type('hash');
=item alias
An alias that the session will be run under. Alias can't be
changed after starting.
=cut
my @alias :Field
:Get('alias');
=item peers
An array of peers
B<set_peers> will only accept ARRAYREF type values.
lib/Agent/TCLI/Transport/Base.pm view on Meta::CPAN
# my $arg = $_[0];
# return (Scalar::Util::looks_like_number($arg) &&
# (int($arg) == $arg));
# }
=back
=head2 METHODS
These methods may be used as is, or subclasses may use them as
starting point.
=over
=cut
sub _init :Init {
my ($self, $args) = @_;
}
=item _start
Get things rolling.
=cut
sub _start :Cumulative {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
# are we up before OIO has finished initializing object?
if (!defined( $self->alias ))
{
$self->Verbose("_start: OIO not started delaying ",0);
$kernel->call('_start');
return;
}
# There is only one command object per TCLI
$kernel->alias_set($self->alias);
$self->Verbose("_start: Starting alias(".$self->alias.")",0);
} # End sub start
=item _stop
Mostly just a placeholder.
=cut
sub _stop :Cumulative {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
lib/Agent/TCLI/Transport/Base.pm view on Meta::CPAN
$kernel->alias_remove( $self->alias );
return("_shutdown ".$self->alias );
}
sub ControlExecute {
my ($kernel, $self, $control, $request ) =
@_[KERNEL, OBJECT, ARG0, ARG1 ];
$self->Verbose("ControlExecute: control(".$control->id.") req(".$request->id.") ");
# Sometimes, control has not started, so we wiat if we have to.
if ( defined($control->start_time) )
{
$kernel->post( $control->id() => 'Execute' => $request );
}
else
{
$kernel->delay('ControlExecute' => 1 => $control, $request );
}
}
=item PackRequest
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
Unlike other Transports, users do not have to be defined
for Transport::Test, as it will load a default user. Local tests are
executed with a Control created for the first user in the stack. Currently,
running with users other than the default has not been tested.
Then one needs to create at least one Agent::TCLI::Testee. The testee
object will be used for the actual tests. See Agent::TCLI::Testee
for the tests available.
Within the actual tests, the Agent::TCLI::Transport::Test (as test_master) offers two
flow/control commands. B<run> is necesary at the end of the tests to start
POE completely and finish the tests. B<done> may be used within the script
to force check for completion of all prior tests. B<done> is a test itself and
will report a success or failure.
=head2 ATTRIBUTES
Unless otherwise indicated, these attrbiute methods are for internal use. They are not
yet restricted because the author does not beleive his imagination is better
than the rest of collective world's. If there are use cases for accessing
the internals, please make the author aware. In the future, they may be
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
=cut
my @dispatch_counter :Field
:Type('numeric')
:All('dispatch_counter');
=item dispatch_retries
The number of times to retry the dispatching of queued requests. Increments are in 5 second blocks. Default is 6 or 30 seconds. This is a user adjustable setting.
When the count is reached, the next test is dispatched without regard to the state of the previous test.
The timeout will not start until dispatching is done or exceeded its retries. This allows for other requests to complete.
B<dispatch_retries> will only contain numeric values.
=cut
my @dispatch_retries :Field
:Type('numeric')
:Arg('name'=>'dispatch_retries','default'=>6)
:Acc('dispatch_retries');
=item timeout_counter
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
The id of the timeout event so that it can be rescheduled if necessary.
=cut
my @timeout_id :Field
# :Type('type')
:All('timeout_id');
=item running
A flag to indicate if we've started the POE kernel fully, rather than just running slices.
This is set when B<run> is called.
B<running> should only contain boolean values.
=cut
my @running :Field
# :Type('boolean')
:Arg('name'=>'running','default'=>0)
:Acc('running');
=item last_testee
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
is 31 seconds if none is supplied.
It takes an option parameter of a test name.
=cut
sub done {
my ($self, $wait, $name) = @_;
$wait = 31 unless defined $wait;
my $start = time();
my $ready = 0;
$self->Verbose($self->alias.":done: start($start) wait($wait)");
# Clean out anything in kernel queue
# $poe_kernel->run_one_timeslice unless ($self->running || $wait == 0 );
# Try to finish up anything left out there.
while ( $start + $wait > time() )
{
$self->Verbose($self->alias.":done: end(".($start + $wait).")time(".time().") ",3);
# make sure there is nothing in request queue
$self->dispatch;
$ready = $self->post_it('done');
# Clean out anything in kernel queue
$poe_kernel->run_one_timeslice;
last if $ready;
next;
}
$ready = $self->post_it('done') if ($wait == 0);
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
is 31 seconds if none is supplied.
It takes an option parameter of a test name.
=cut
sub done_id {
my ($self, $id, $wait, $name) = @_;
$wait = 31 unless defined $wait;
my $start = time();
my $ready = 0;
# validate id
unless ( defined($id) && $id )
{
# Use last id if not supplied
$id = $self->make_id( $request_count[$$self] );
}
$self->Verbose($self->alias.":done_id: id($id) start($start) wait($wait)",1);
# Clean out anything in kernel queue
# $poe_kernel->run_one_timeslice unless ($self->running || $wait == 0 );
# Try to finish up anything left out there.
while ( $start + $wait > time() )
{
$self->Verbose($self->alias.":done_id: end(".($start + $wait).") time(".time().") ",3);
# make sure there is nothing in request queue
$self->dispatch;
$ready = $self->post_it('done');
# Clean out anything in kernel queue
$poe_kernel->run_one_timeslice;
last if $ready;
next;
}
$ready = $self->post_it('done') if ($wait == 0);
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
=cut
sub _preinit :PreInit {
my ($self,$args) = @_;
$args->{'alias'} = 'transport_test' unless defined( $args->{'alias'} ) ;
$args->{'session'} = POE::Session->create(
object_states => [
$self => [ qw(
_start
_stop
_shutdown
_child
_default
Dispatch
SendChangeContext
SendRequest
PostResponse
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
# who cares, send it now.
{
$post_it = 1;
}
$self->Verbose($self->alias.":post_it: ($post_it)");
return($post_it);
}
=item responses_contiguous ( )
Sets responses_max_contiguous correctly by starting at the last value and
incrementing until a response has not been recived. Return
responses_max_contiguous.
=cut
sub responses_contiguous {
my ($self, $id) = @_;
while ( defined($self->responses->{
$self->make_id( $self->responses_max_contiguous + 1) } ) )
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
# $self->Verbose($self->alias.":Dispatch: STALLED requests(".$self->depth_requests.") ",0 );
# # Stalled out
# foreach my $test ( @{$self->requests} )
# {
# $self->Verbose($self->alias.":Dispatch: test dump(".$test->dump(1).") ");
# }
# return;
# }
else
{
#start counting to doom...
$dispatch_counter[$$self]++;
$kernel->delay('Dispatch', $delay, $delay );
}
return('Dispatch_'.$self->alias);
}
=item PostRequest
B<PostReuqest> is a required POE event handler for all Transports. Well, all
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
=cut
sub PostResponse {
my ($kernel, $self, $sender, $response) =
@_[KERNEL, OBJECT, SENDER, ARG0];
$self->Verbose($self->alias.":PostResponse: sender(".$sender->ID.") Code(".$response->code.") \n");
# Test always terminates a response transmission. The buck stops here,
# unlike other transports
# TODO Need to figure out how to decide it is time to start checking the tests!
# Hmm. I donn't want to optimize this better with another object right now.
# Push response into a responses array in a hash keyed on id.
push( @{ $responses[$$self]->{$response->id} }, $response );
$self->Verbose($self->alias.":PostResponse: responses(".@{ $responses[$$self]->{$response->id} }.
") ",3,$responses[$$self]->{$response->id} );
# Work off of the first response for tracking.
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
# Put time in request for tracking
$request->set_time(time());
if ( $request->sender->[0] eq $self->alias )
{
$self->Verbose($self->alias.":SendRequest: local request \n");
$self->Verbose($self->alias.":SendRequest: request dump ".$request->dump(1),3 );
# Get a Control for the test-master user loaded into peers.
my $control = $self->GetControl( $self->peers->[0]->id, $self->peers->[0] );
# Post to our Control
# Sometimes, control has not started, so we wiat if we have to.
if ( defined($control->start_time) )
{
$kernel->post( $control->id => 'Execute' => $request );
}
else
{
$kernel->delay('ControlExecute' => 1 => $control, $request );
}
}
else
{
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
foreach my $package ( @{$self->control_options->{'packages'} })
{
$kernel->post( $package->name => '_shutdown' );
}
# $kernel->alias_remove( $self->alias );
return ('_shutdown '.$self->alias )
}
sub _start {
my ($kernel, $session, $self) = @_[KERNEL, SESSION, OBJECT];
# Trying to run this as cumulative is not working. Not sure why.
# Just being inefficient instead of debugging.
# are we up before OIO has finished initializing object?
if (!defined( $self->alias ))
{
$self->Verbose($session->ID.":_start: OIO not started delaying ");
$kernel->yield('_start');
return;
}
$kernel->alias_set($self->alias);
$self->Verbose($self->alias.":_start: Starting alias(".$self->alias.")");
# Set up recording.
$self->requests_sent(0) ;
$self->requests_complete(0);
# initialize counters
$self->dispatch_counter(0);
$self->timeout_counter(0);
# This will call timeout in 5 seconds
lib/Agent/TCLI/Transport/Test.pm view on Meta::CPAN
# before we stop by default.
$timeout_id[$$self] = $kernel->delay_set( 'Timeout', 5, 5 );
# well, tha above would be true if the kernel was running gung ho. But we're
# calling timeslices willy nilly until all requests are queued, so it turns out
# that Timeout gets called in every timeslice regardless of delay, but
# this is good because it is the one queud event that keeps everything
# from stopping.
# When debugging POE Event streams, this might help.
return('_start'.$self->alias);
}
=item _stop
This POE event handler is called when POE stops a Transport.
=cut
sub _stop {
my ($kernel, $session, $self) = @_[KERNEL, SESSION, OBJECT];
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
Holds the Net::XMPP::Roster if enabled. To enable the roster,
a paramater of 'roster' => 1, must be passed in with new.
B<roster> will contain a Net::XMPP::Roster object after initialization if enabled.
=cut
my @roster :Field
:All('roster');
=item server_time
The time at the server. Useful for determining if messages were sent before we started up.
B<server_time> should only contain hash values.
=cut
my @server_time :Field
# :Type('hash')
:All('server_time');
=item group_mode
The default setting to determine how to interact with groups. Options are:
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
}
sub _preinit :Preinit {
my ($self, $args) = @_;
$args->{'alias'} = 'transport_xmpp' unless defined( $args->{'alias'} );
$args->{'session'} = POE::Session->create(
object_states => [
$self => [ qw(
_start
_stop
_shutdown
_default
_child
ControlExecute
Disconnected
JoinPeerRooms
JoinChatRoom
Login
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
}
=back
=head2 METHODS
=over
=item start
Get things rolling. Starts up a POE::Component::Jabber::Client using the user
provided config info.
=cut
sub _start {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
# are we up before OIO has finished initializing object?
if (!defined( $self->alias ))
{
$kernel->yield('_start');
return;
}
$self->Verbose("_start: ".$self->alias." Starting up");
# OK, now we can start up POE stuff.
$kernel->alias_set($self->alias);
my $xmpp = Net::Jabber::Client->new(
'debuglevel' => $xmpp_debug[$$self],
'debugfile' => 'stdout',
);
# Add a namespace for IQ nodes to embed YAML output
$xmpp->AddNamespace(
ns => "tcli:request",
tag => "tcli",
xpath => {
'Version' => { 'path' => 'version/text()' },
'Yaml' => { 'path' => 'yaml/text()' },
'Request' => { 'type' => 'master'},
}
);
# $self->Verbose("_start: Setting General XMPP Callbacks" , 2 );
# $xmpp->SetCallBacks(
# 'send' => $session->postback('VerboseCallBack'),
# 'receive' => $session->postback('VerboseCallBack'),
# 'presence' => $session->postback('recv_presence'),
# 'iq' => $session->postback('recv_iq'),
# );
$self->Verbose("_start: Setting XMPP Message Callbacks" , 2 );
$xmpp->SetMessageCallBacks(
'normal' => $session->postback('recvmsg'),
'chat' => $session->postback('recvmsg'),
'groupchat' => $session->postback('recvmsgGroupchat'),
'headline' => $session->postback('recvmsgHeadline'),
'error' => $session->postback('recvmsgError'),
);
# $xmpp->SetPresenceCallBacks(
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
'get' => $session->postback('recv_iqRequest'),
# 'set' => function,
'result'=> $session->postback('recv_iqResponse'),
},
);
$self->set(\@xmpp, $xmpp);
$kernel->yield('Login') if (defined( $self->jpassword ));
return ($self->alias."_start whohoo");
} # End sub start
=item stop
Mostly just a placeholder.
=cut
sub _stop {
my ($kernel, $self, $session) =
@_[KERNEL, OBJECT, SESSION];
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
sub Online {
my ($kernel, $self, ) =
@_[KERNEL, OBJECT, ];
$self->Verbose("Online: \n" ,1);
my %server_time = $self->xmpp->TimeQuery('mode'=>'block');
$self->Verbose("Online: server_time($server_time{display})", 1,\%server_time );
$self->set(\@server_time, $server_time{utc});
# start roster
if ($self->roster)
{
$self->Verbose("Online: enabling Roster ");
$self->set(\@roster, $self->xmpp->Roster);
}
if (defined($self->control_options) )
{
$self->control_options->{'local_address'} = $self->Address
unless defined($self->control_options->{'local_address'});
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
$request->unshift_sender($self->alias);
$request->unshift_postback('PostResponse');
my $control = $self->GetControlForNode( $msg );
return unless $control;
$self->Verbose("recv_iqRequest: sending to contol(".$control->id().") \n",1);
$self->Verbose("recv_iqRequest: control dump.... \n".$control->dump(1), 5 );
# Sometimes, control has not started, so we wiat if we have to.
if ( defined($control->start_time) )
{
$kernel->post( $control->id() => 'Execute' => $request );
}
else
{
$kernel->delay('ControlExecute' => 1 => $control, $request );
}
}
sub recv_iqResponse {
lib/Agent/TCLI/Transport/XMPP.pm view on Meta::CPAN
} # end sub xmpp_send_msg
=item GetControlForNode ( node )
Determines the control from a node and returns the control object.
Takes a node parameter and returns the hash key to the proper control
object in the controls array. If the control object is not in the array,
it will add it.
When a new control object is created, a new Control session must be started
for the control and that is handled here as well.
=cut
sub GetControlForNode {
my ($self, $node) = @_;
$self->Verbose("GetControlForNode: node(".ref($node).") \n");
my $type = $node->GetType;
my $user = $node->GetFrom('jid');
lib/Agent/TCLI/User.pm view on Meta::CPAN
ID of user in a form acceptable to the protocol.
XMPP/Jabber IDs MUST not include resource information.
=cut
my @id :Field :All('id');
=item protocol
Protocol that user is allowed access on. Currently only xmpp and xmpp-groupchat
are supported by Transport::XMPP. If the protocol is xmpp-groupchat, the
Transport will automatically join the conference room at start-up.
=cut
my @protocol :Field :All('protocol');
=item auth
Authorization level of user. MUST be one of these values:
B<reader> has read access
B<writer> has write access
B<master> has root access