Workflow Perl module with validator

I am trying to get everything working with the perl Workflow module - http://search.cpan.org/~jonasbn/Workflow/

I managed to figure out how this works with workflows, actions, conditions, and everything, but I can't get it to apply the validator class to an action.

My _init method from the validator downloads and prints the line that I put there for testing, but the verification method never starts. Also, when dumping $ self-> get_validators () from the action class, I get an empty list.

I created a short example, so please try and help if you see a problem. Tnx!

link to the code - https://github.com/vmcooper/perl_workflow_test

Program launch

The program begins with

Answer: London If you answer right the action should change state to 'finished'. Try answering wrong first. Capital city of England: 

if you answer Birmingham he should write

 Your answer is being validated! 

and ask the question again.

When you answer "London", he should

 Correct! Current state of workflow is - finished 

edit Now it writes “Correct! The current state of the workflow is completed” regardless of your answer.

workflow_test.pl

 use strict; use Log::Log4perl qw( get_logger ); use Workflow::Factory qw( FACTORY ); Log::Log4perl::init( 'log4perl.conf' ); system('clear'); # Stock the factory with the configurations; we can add more later if we want FACTORY->add_config_from_file( workflow => 'workflow.xml', action => 'action.xml', persister => 'persister.xml', validator => 'validator.xml' ); my $workflow = FACTORY->create_workflow( "Workflow1" ); my $context = $workflow->context; while ( $workflow->state eq "INITIAL" ) { print "If you answer right the action should change state to 'finished'. Try answering wrong first.\n"; my $city = get_response( "Capital city of England: " ); print "You answered - $city\n"; $workflow->execute_action( 'action1' ); if( $workflow->state eq "INITIAL" ) { print "Your answer is wrong! try again!\n\n"; } } print "\nCorrect! Current state of workflow is - ".$workflow->state."\n\n"; # Generic routine to read a response from the command-line (defaults, # etc.) Note that return value has whitespace at the end/beginning of # the routine trimmed. sub get_response { my ( $msg ) = @_; print $msg; my $response = <STDIN>; chomp $response; $response =~ s/^\s+//; $response =~ s/\s+$//; return $response; } 

workflow.xml

 <workflow> <type>Workflow1</type> <time_zone>local</time_zone> <description>This is my workflow.</description> <persister>Persister1</persister> <state name="INITIAL"> <action name="action1" resulting_state="finished"/> </state> <state name="finished" /> </workflow> 

action.xml

 <actions> <action name="action1" class="App::Action::Action1" > <validator name="validator1"> <arg>$city</arg> </validator> </action> </actions> 

validator.xml

 <validators> <validator name="validator1" class="App::Validator::Validator1"> <param name="answer" value="London" /> </validator> </validators> 

App :: Action :: Action1.pm

 package App::Action::Action1; use strict; use base qw( Workflow::Action ); use Workflow::Exception qw( validation_error configuration_error ); use Data::Dumper; sub new { my $class = shift; my $self = {}; bless ($self, $class); return $self; } sub execute { my $self = shift; my $wf = shift; print "App::Action::Action1::Execute\n"; print "Validators: ".Dumper($self->get_validators())."\n"; } 1; 

App :: Validator :: Validator1.pm

 package App::Validator::Validator1; use strict; use base qw( Workflow::Validator ); use Workflow::Exception qw( validation_error configuration_error ); use Data::Dumper; use Carp qw(carp); sub _init { my ( $self, $params ) = @_; unless ( $params->{answer} ) { configuration_error "You must define a value for 'answer' in ", "declaration of validator ", $self->name; } if ( ref $params->{answer} ) { configuration_error "The value for 'answer' must be a simple scalar in ", "declaration of validator ", $self->name; } print "Answer: ".$params->{answer}."\n"; $self->{ answer => $params->{answer} }; } sub validate { my ( $self, $wf, $city ) = @_; print "Your answer is being validated!\n"; print "Your answer is - ".$city."\n"; my $check; if ( $city eq $self->{answer} ){ $check = 1; } else { $check = 0; } unless ( $check ) { validation_error "Validation error!"; } } 1; 

Edit: If I delete a work object immediately after creation and before any action is performed, I get the following:

 Workflow: $VAR1 = bless( { '_states' => { 'INITIAL' => bless( { ..., '_actions' => { 'action1' => { 'resulting_state' => 'finished', 'name' => 'action1' } }, '_factory' => bless( { ..., '_action_config' => { 'default' => { 'action1' => { 'name' => 'action1', 'class' => 'App::Action::Action1', 'validator' => [ { 'arg' => [ '$city' ], 'name' => 'validator1' } ] } } }, '_validators' => { 'validator1' => bless( { 'name' => 'validator1', 'class' => 'App::Validator::Validator1', 'PARAMS' => {} }, 'App::Validator::Validator1' ) }, '_validator_config' => { 'validator1' => { 'answer' => 'London', 'name' => 'validator1', 'class' => 'App::Validator::Validator1' } }, ... }, 'Workflow::Factory' ), 'type' => 'Workflow1', 'PARAMS' => {} }, 'Workflow::State' ), 'finished' => $VAR1->{'_states'}{'INITIAL'}{'_factory'}{'_workflow_state'}{'Workflow1'}[1] }, ... }, 'Workflow' ); 

As you can see, the validator is here, and everything is configured and looks as if it is normal, but the validator is not applied.

+6
source share
2 answers

It looks like we have to wait a bit, or we can participate in the project to fulfill this function.

Go to the heading "get_validators" and you will see the mark "#TODO". I'm not sure if this means the documentation should be executed or the code, but I looked at the code a bit and it seems like the code should be executed for this function. http://search.cpan.org/~jonasbn/Workflow-1.41/lib/Workflow/Factory.pm

Correct me if I am wrong.

0
source

There were several problems in your example.

Action1.pm has a constructor, this interferes with inheritance, so it should be deleted, leaving your action class as follows

 package App::Action::Action1; use strict; use base qw( Workflow::Action ); use Workflow::Exception qw( validation_error configuration_error ); use Data::Dumper; sub execute { my $self = shift; my $wf = shift; print "App::Action::Action1::Execute\n"; print "Validators: ".Dumper($self->get_validators())."\n"; } 1; 

The main problem that your application receives from the user, but you never load it into the workflow. This is done using context, for example:

 $context->param( answer => $city ); 

The validator should look like this:

 package App::Validator::Validator1; use strict; use base qw( Workflow::Validator ); use Workflow::Exception qw( validation_error configuration_error ); use Data::Dumper; use Carp qw(carp); sub _init { my ( $self, $params ) = @_; unless ( $params->{answer} ) { configuration_error "You must define a value for 'answer' in ", "declaration of validator ", $self->name; } if ( ref $params->{answer} ) { configuration_error "The value for 'answer' must be a simple scalar in ", "declaration of validator ", $self->name; } print "Answer: ".$params->{answer}."\n"; $self->{answer} = $params->{answer}; } sub validate { my ( $self, $wf ) = @_; my $city = $wf->context->param('answer'); print "Your answer is being validated!\n"; print "Your answer is - ".$city."\n"; my $check; if ( $city eq $self->{answer} ){ $check = 1; } else { $check = 0; } unless ( $check ) { validation_error "Validation error!"; } } 1; 

And your main application should look like this:

 use strict; use Log::Log4perl qw( get_logger ); use Workflow::Factory qw( FACTORY ); use lib qw(lib); Log::Log4perl::init( 'log4perl.conf' ); system('clear'); # Stock the factory with the configurations; we can add more later if we want FACTORY->add_config_from_file( workflow => 'workflow.xml', action => 'action.xml', persister => 'persister.xml', validator => 'validator.xml' ); my $workflow = FACTORY->create_workflow( "Workflow1" ); my $context = $workflow->context; while ( $workflow->state eq "INITIAL" ) { print "If you answer right the action should change state to 'finished'. Try answering wrong first.\n"; my $city = get_response( "Capital city of England: " ); print "You answered - $city\n"; $context->param( answer => $city ); $workflow->execute_action( 'action1' ); if( $workflow->state eq "INITIAL" ) { print "Your answer is wrong! try again!\n\n"; } } print "\nCorrect! Current state of workflow is - ".$workflow->state."\n\n"; # Generic routine to read a response from the command-line (defaults, # etc.) Note that return value has whitespace at the end/beginning of # the routine trimmed. sub get_response { my ( $msg ) = @_; print $msg; my $response = <STDIN>; chomp $response; $response =~ s/^\s+//; $response =~ s/\s+$//; return $response; } 

I understand your confusion, because the documentation does not reflect this fact properly and cannot be read from the sample application in the distribution. I will update the relevant documentation.

-1
source

Source: https://habr.com/ru/post/980924/


All Articles