BPM-Engine

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

        \%columns_values, $state_transition

    *   Returns: ProcessInstanceRow

    Sets the new state of the process instance given a process instance id
    or a process instance object and a state transition name.

    The following state transitions are possible:

    start
        Changes the process instance state from "open.not_running.ready" to
        "open.running".

    suspend
        Changes the process instance state from "open.running" to
        "open.not_running.suspended".

    resume
        Changes the process instance state from "open.not_running.suspended"
        to "open.running".

    terminate
        Changes the process instance state from "open.not_running.ready",
        "open.running" or "open.not_running.suspended" to
        "closed.cancelled.terminated". This is an end state (no more state
        transitions possible).

    abort
        Changes the process instance state from "open.not_running.ready",
        "open.running" or "open.not_running.suspended" to
        "closed.cancelled.aborted". This is an end state (no more state
        transitions possible).

    finish
        Changes the process instance state from "open.running" to
        "closed.completed". This is an end state (no more state transitions
        possible).

    An exception will be thrown for invalid state transitions, for example
    when the process instance is not in the right state to allow the

README  view on Meta::CPAN

        \%columns_values, $state_transition

    *   Returns: ActivityInstanceRow

    Sets the new state of the activity instance given a activity instance id
    or a activity instance object and a state transition name.

    The following state transitions are possible:

    start
        Changes the activity instance state from "open.not_running.ready" to
        "open.running.not_assigned".

    assign
        Changes the activity instance state from "open.not_running.ready" or
        "open.running.not_assigned" to "open.running.assigned".

    reassign
        Valid state transition when the activity instance state is
        "open.running.assigned". Does not actually change the state.

    unassign
        Changes the activity instance state from "open.running.assigned" to
        "open.running.not_assigned".

    suspend
        Changes the activity instance state from "open.running.assigned" to
        "open.not_running.suspended".

    resume
        Changes the activity instance state from
        "open.not_running.suspended" to "open.running.assigned".

    abort
        Changes the activity instance state from "open.not_running.ready" or
        "open.running.assigned" to "closed.cancelled.aborted". This is an
        end state (no more state transitions possible).

    finish
        Changes the activity instance state from "open.not_running.ready" or
        "open.running.assigned" to "closed.completed". This is an end state
        (no more state transitions possible).

   activity_instance_attribute
        $attr = $engine->activity_instance_attribute($ai_id, 'some_var');
        $attr = $engine->activity_instance_attribute($ai_id, 'some_var', 'new_value');

    *   Arguments: $activity_instance_id | ActivityInstanceRow |
        \%columns_values, $attribute_name, $attribute_value?

inc/Test/More.pm  view on Meta::CPAN

    # Effectively turn %Refs_Seen into a stack.  This avoids picking up
    # the same referenced used twice (such as [\$a, \$a]) to be considered
    # circular.
    local %Refs_Seen = %Refs_Seen;

    {
        $tb->_unoverload_str( \$e1, \$e2 );

        # Either they're both references or both not.
        my $same_ref = !( !ref $e1 xor !ref $e2 );
        my $not_ref = ( !ref $e1 and !ref $e2 );

        if( defined $e1 xor defined $e2 ) {
            $ok = 0;
        }
        elsif( !defined $e1 and !defined $e2 ) {
            # Shortcut if they're both undefined.
            $ok = 1;
        }
        elsif( _dne($e1) xor _dne($e2) ) {
            $ok = 0;
        }
        elsif( $same_ref and( $e1 eq $e2 ) ) {
            $ok = 1;
        }
        elsif($not_ref) {
            push @Data_Stack, { type => '', vals => [ $e1, $e2 ] };
            $ok = 0;
        }
        else {
            if( $Refs_Seen{$e1} ) {
                return $Refs_Seen{$e1} eq $e2;
            }
            else {
                $Refs_Seen{$e1} = "$e2";
            }

lib/BPM/Engine.pm  view on Meta::CPAN


Sets the new state of the process instance given a process instance id or a 
process instance object and a state transition name.

The following state transitions are possible:

=over 4

=item start

Changes the process instance state from C<open.not_running.ready> to 
C<open.running>.

=item suspend

Changes the process instance state from C<open.running> to 
C<open.not_running.suspended>.

=item resume

Changes the process instance state from C<open.not_running.suspended> to 
C<open.running>.

=item terminate

Changes the process instance state from C<open.not_running.ready>, 
C<open.running> or C<open.not_running.suspended> to 
C<closed.cancelled.terminated>. This is an end state (no more state transitions
possible).

=item abort

Changes the process instance state from C<open.not_running.ready>,
C<open.running> or C<open.not_running.suspended> to
C<closed.cancelled.aborted>. This is an end state (no more state transitions 
possible).

=item finish

Changes the process instance state from C<open.running> to C<closed.completed>. 
This is an end state (no more state transitions possible).

=back

lib/BPM/Engine.pm  view on Meta::CPAN


Sets the new state of the activity instance given a activity instance id or a
activity instance object and a state transition name.

The following state transitions are possible:

=over 4

=item start

Changes the activity instance state from C<open.not_running.ready> to
C<open.running.not_assigned>.

=item assign

Changes the activity instance state from C<open.not_running.ready> or 
C<open.running.not_assigned> to C<open.running.assigned>.

=item reassign

Valid state transition when the activity instance state is 
C<open.running.assigned>. Does not actually change the state.

=item unassign

Changes the activity instance state from C<open.running.assigned> to 
C<open.running.not_assigned>.

=item suspend

Changes the activity instance state from C<open.running.assigned> to
C<open.not_running.suspended>.

=item resume

Changes the activity instance state from C<open.not_running.suspended> to
C<open.running.assigned>.

=item abort

Changes the activity instance state from C<open.not_running.ready> or
C<open.running.assigned> to C<closed.cancelled.aborted>. This is an end state 
(no more state transitions possible).

=item finish

Changes the activity instance state from C<open.not_running.ready> or 
C<open.running.assigned> to C<closed.completed>. This is an end state (no more 
state transitions possible).

=back

=head3 activity_instance_attribute

    $attr = $engine->activity_instance_attribute($ai_id, 'some_var');
    $attr = $engine->activity_instance_attribute($ai_id, 'some_var', 'new_value');

lib/BPM/Engine/Store/ResultBase/ActivityInstance.pm  view on Meta::CPAN

        $W->instance_class('BPM::Engine::Store::Result::ActivityInstanceState');
        }
    return $W;
    }

no Moose::Role;

1;
__DATA__
workflow:
    initial_state: open.not_running.ready
    states:
    - name: open.not_running.ready
      transitions:
        - name    : start
          to_state: open.running.not_assigned
        - name    : assign
          to_state: open.running.assigned
        - name    : abort
          to_state: closed.cancelled.aborted
        - name    : finish
          to_state: closed.completed
    - name: open.running.not_assigned
      transitions:
        - name    : assign
          to_state: open.running.assigned
    - name: open.running.assigned
      transitions:
        - name    : reassign
          to_state: open.running.assigned
        - name    : unassign
          to_state: open.running.not_assigned        
        - name    : suspend
          to_state: open.not_running.suspended
        - name    : abort
          to_state: closed.cancelled.aborted
        - name    : finish
          to_state: closed.completed
    - name: open.not_running.suspended
      transitions:
        - name    : resume
          to_state: open.running.assigned
    - name: closed.cancelled.aborted
    - name: closed.completed

lib/BPM/Engine/Store/ResultBase/ProcessInstance.pm  view on Meta::CPAN

        $W->instance_class('BPM::Engine::Store::Result::ProcessInstanceState');
        }
    return $W;
    }

no Moose::Role;

1;
__DATA__
workflow:
    initial_state: open.not_running.ready
    states:
    # initial state - the workflow is active, but has not been started yet
    - name: open.not_running.ready
      transitions:
        - name    : start
          to_state: open.running
        - name    : terminate
          to_state: closed.cancelled.terminated
        - name    : abort
          to_state: closed.cancelled.aborted
    # the workflow is executing
    - name: open.running
      transitions:
        - name    : suspend
          to_state: open.not_running.suspended
        - name    : terminate
          to_state: closed.cancelled.terminated
        - name    : abort
          to_state: closed.cancelled.aborted
        - name    : finish
          to_state: closed.completed
    # execution was temporarily suspended
    - name: open.not_running.suspended
      transitions:
        - name    : resume
          to_state: open.running
        - name    : terminate
          to_state: closed.cancelled.terminated
        - name    : abort
          to_state: closed.cancelled.aborted
    - name: closed.cancelled.aborted
    - name: closed.cancelled.terminated
    - name: closed.completed

share/schemas/XMLSchema.xsd  view on Meta::CPAN

    base (as an attribute name): denotes an attribute whose value
         provides a URI to be used as the base for interpreting any
         relative URIs in the scope of the element on which it
         appears; its value is inherited.  This name is reserved
         by virtue of its definition in the XML Base specification.

    id   (as an attribute name): denotes an attribute whose value
         should be interpreted as if declared to be of type ID.
         The xml:id specification is not yet a W3C Recommendation,
         but this attribute is included here to facilitate experimentation
         with the mechanisms it proposes.  Note that it is _not_ included
         in the specialAttrs attribute group.

    lang (as an attribute name): denotes an attribute whose value
         is a language code for the natural language of the content of
         any element; its value is inherited.  This name is reserved
         by virtue of its definition in the XML specification.

    space (as an attribute name): denotes an attribute whose
         value is a keyword indicating what whitespace processing
         discipline is intended for the content of the element; its

t/02-store/07-pi-workflow.t  view on Meta::CPAN

my $schema = schema();
my $package = $schema->resultset('Package')->create({});
my $process = $package->add_to_processes({});
my $rs_state = $schema->resultset('ProcessInstanceState');

is($rs_state->count, 0);

my $pi = $process->new_instance();

isa_ok($pi->workflow_instance, 'BPM::Engine::Store::Result::ProcessInstanceState');
is($pi->workflow_instance->state->name, 'open.not_running.ready');
is($pi->state, 'open.not_running.ready');
is($rs_state->count, 1);
#is($schema->resultset('ProcessInstanceState')->search_rs->count, 1);

ok($pi->apply_transition('start'));
is($pi->workflow_instance->state->name, 'open.running');
is($pi->state, 'open.running');
#is($schema->resultset('ProcessInstanceState')->search_rs->count, 2);
is($rs_state->count, 2);

$pi->apply_transition('suspend');
is($pi->workflow_instance->state->name, 'open.not_running.suspended');
#is($schema->resultset('ProcessInstanceState')->search_rs->count, 3);
is($rs_state->count, 3);

$pi->apply_transition('resume');
is($pi->workflow_instance->state->name, 'open.running');

$pi->apply_transition('finish');
is($pi->workflow_instance->state->name, 'closed.completed');
is($rs_state->count, 5);

t/02-store/09-ai.t  view on Meta::CPAN


isa_ok($ai->workflow_instance, 'BPM::Engine::Store::Result::ActivityInstanceState');
ok(!$ai->split);
isa_ok($ai->attributes, 'DBIx::Class::ResultSet');
#can_ok($ai, qw/join_should_fire/);

#-- workflow role

isa_ok($ai->workflow, 'Class::Workflow');
does_ok($ai->workflow_instance, 'Class::Workflow::Instance');
is($ai->workflow_instance->state->name, 'open.not_running.ready');
is($ai->state, 'open.not_running.ready');

done_testing();

t/02-store/11-ai-workflow.t  view on Meta::CPAN


my $s1 = $wi->state;
#isa_ok($s1,'Class::Workflow::State::Simple');
isa_ok($s1,'BPM::Engine::Class::Workflow::State');
#warn Dumper $s1->name;
my $s2 = $wf->get_state($s1->name);
#warn Dumper $s2->name;
#isa_ok($s2,'Class::Workflow::State::Simple');
isa_ok($s2,'BPM::Engine::Class::Workflow::State');

is($ai->workflow_instance->state->name, 'open.not_running.ready', 'State set to open.not_running.not_assigned');
is($ai->state, 'open.not_running.ready');

my $rs = $schema->resultset('ActivityInstanceState')->search_rs;
is($rs->count, 1);

$ai->apply_transition('start');
is($ai->workflow_instance->state->name, 'open.running.not_assigned');
is($rs->count, 2);

$ai->apply_transition('assign');
is($ai->workflow_instance->state->name, 'open.running.assigned');
is($rs->count, 3);

$ai->apply_transition('suspend');
is($ai->workflow_instance->state->name, 'open.not_running.suspended', 'suspended');
is($rs->count, 4);

$ai->apply_transition('resume');
is($ai->workflow_instance->state->name, 'open.running.assigned', 'resumed');

$ai->apply_transition('reassign');
is($ai->workflow_instance->state->name, 'open.running.assigned', 'reassigned');

my $ai2 = $ai->clone;
is($ai2->workflow_instance->state->name, 'open.not_running.ready', 'ready');

$ai2->apply_transition('assign');
is($ai2->workflow_instance->state->name, 'open.running.assigned', 'assigned');

#$ai2->update;
$ai->apply_transition('abort');
is($ai2->workflow_instance->state->name, 'open.running.assigned', 'open.running.assigned');
is($ai->workflow_instance->state->name, 'closed.cancelled.aborted');

$ai2->apply_transition('finish');

t/04-run/02-runner.t  view on Meta::CPAN

diag('inclusive-tasks');
if(1) {
  my $params = { splitA => undef, splitB => undef, splitB2 => 'C' };
  ($runner, $process, $pi) = runner($engine, 'unstructured-inclusive-tasks', $params);
  $pi->apply_transition('start');

  my $act = $process->start_activities->[0];
  my $aiA = $act->new_instance({
    process_instance_id => $pi->id
    });
  is($aiA->workflow_instance->state->name, 'open.not_running.ready');
  $runner->start_activity($act, $aiA, 1);
  is($aiA->workflow_instance->state->name, 'open.running.assigned');

  #$runner->complete_activity($act, $aiA, 1);
  complete_active();  # complete A

  $aiA->discard_changes();
  is($aiA->workflow_instance->state->name, 'closed.completed');

  diag "--- A completed, B active, B1 deferred";

t/04-run/02-runner.t  view on Meta::CPAN

diag('Local Synchronizing Merge');
if(1){
  my $params = { multi_choice => 'B,C', deferred_choice => undef };
  ($runner, $process, $pi) = runner($engine, 'wcp37', $params);
  $pi->apply_transition('start');

  my $act = $process->start_activities->[0];
  my $aiMC = $act->new_instance({
    process_instance_id => $pi->id
    });
  is($aiMC->workflow_instance->state->name, 'open.not_running.ready');

  $runner->start_activity($act, $aiMC, 1);
  is($aiMC->workflow_instance->state->name, 'open.running.assigned');
  test_state(completed => [], active => ['MC'], deferred => []);

  complete_active(); # complete MC
  test_state(completed => ['MC'], active => ['B','C'], deferred => []);

  complete_active(); # complete B+C
  test_state(completed => [qw/B C MC/], active => [qw/DC/], deferred => [qw/SM/]);

t/04-run/02-runner.t  view on Meta::CPAN

if(1) {

  my $params = { multi_choice => 'B,XOR', deferred_choice => undef };
  ($runner, $process, $pi) = runner($engine, 'wcp38', $params);
  $pi->apply_transition('start');

  my $act = $process->start_activities->[0];
  my $aiMC = $act->new_instance({
    process_instance_id => $pi->id
    });
  is($aiMC->workflow_instance->state->name, 'open.not_running.ready');

  $runner->start_activity($act, $aiMC, 1);
  is($aiMC->workflow_instance->state->name, 'open.running.assigned');

  complete_active();  # complete MC
  $aiMC->discard_changes();
  is($aiMC->workflow_instance->state->name, 'closed.completed');
  is($aiMC->state, 'closed.completed');
  test_state(completed => ['MC'], active => ['B','XOR'], deferred => []);

t/04-run/02-runner.t  view on Meta::CPAN

#C-DC closes cycle, sets prev DC.join(XOR) to 'joined'
  my $params = { inner_loop => 1, outer_loop => 1 };
  ($runner, $process, $pi) = runner($engine, 'wcp10b2', $params);

  $pi->apply_transition('start');

  my $act = $process->start_activities->[0];
  my $ai = $act->new_instance({
    process_instance_id => $pi->id
    });
  is($ai->workflow_instance->state->name, 'open.not_running.ready');
  $runner->start_activity($act, $ai, 1);
  is($ai->workflow_instance->state->name, 'open.running.assigned');

  complete_active();  # complete Start
  test_state(completed => [qw/Start/], active => [qw/A/], deferred => []);

  complete_active();  # complete A-Join1
  test_state(completed => [qw/Start A/], active => [qw/B/], deferred => []);

  complete_active();  # complete B-Join2

t/04-run/10-engine.t  view on Meta::CPAN


#-- get_process_instance

throws_ok( sub { $engine->get_process_instance() },          qr/Validation failed/, 'Validation failed' );
throws_ok( sub { $engine->get_process_instance('string') },  qr/Validation failed/, 'Validation failed' );
throws_ok( sub { $engine->get_process_instance(987654321) }, qr/Process instance '987654321' not found/, 'Validation failed' );
throws_ok( sub { $engine->get_process_instance(987654321) }, 'BPM::Engine::Exception::Database', 'Validation failed' );

ok($first_pi = $engine->get_process_instance($first_pi->id));
isa_ok($first_pi, 'BPM::Engine::Store::Result::ProcessInstance');
is($first_pi->workflow_instance->state->name, 'open.not_running.ready');
is($first_pi->state, 'open.not_running.ready');

#-- start_process_instance

throws_ok( sub { $engine->start_process_instance() },          qr/Validation failed/, 'Validation failed' );
throws_ok( sub { $engine->start_process_instance('string') },  qr/Validation failed/, 'Validation failed' );
throws_ok( sub { $engine->start_process_instance(987654321) }, qr/Process instance '987654321' not found/, 'Validation failed' );
throws_ok( sub { $engine->start_process_instance(987654321) }, 'BPM::Engine::Exception::Database', 'Validation failed' );

my $args = { splitA => 'B1', splitB => 'B1' };

t/04-run/10-engine.t  view on Meta::CPAN

#-- abort_process_instance

#-- process_instance_attribute

#-- change_process_instance_state

my $pi1 = $engine->create_process_instance($process);

throws_ok(
    sub { $engine->change_process_instance_state($pi1, 'open.your.eyes') },
    qr/There's no 'open.your.eyes' transition from open.not_running.ready/,
    'Invalid process instance state change failed'
    );

is($pi1->state, 'open.not_running.ready');
my $st = $engine->change_process_instance_state($pi1, 'start');
is($pi1->state, 'open.running');
$engine->change_process_instance_state($pi1, 'terminate');
is($pi1->state, 'closed.cancelled.terminated');

my $pi2 = $engine->create_process_instance($process);
$engine->change_process_instance_state($pi2, 'start');
$engine->change_process_instance_state($pi2, 'abort');
is($pi2->state, 'closed.cancelled.aborted');

my $pi3 = $engine->create_process_instance($process);
$engine->change_process_instance_state($pi3, 'start');
$engine->change_process_instance_state($pi3, 'suspend');
is($pi3->state, 'open.not_running.suspended');
$engine->change_process_instance_state($pi3, 'resume');
is($pi3->state, 'open.running');
$engine->change_process_instance_state($pi3, 'finish');
is($pi3->state, 'closed.completed');

#-- delete_process_instance

is($engine->get_process_instances->count, 5, 'First process instance found');
ok($engine->delete_process_instance($pi));
is($engine->get_process_instances->count, 4, 'First process instance deleted');



( run in 0.304 second using v1.01-cache-2.11-cpan-26ccb49234f )