Drools get facts from database at runtime - drools

I need a little help with Drools eval and variable assigning.
rule "check that no previously submitted requests exist"
when
$user : UserFormField( name == 'employeeId', value != null )
$repository : Repository( )
$activeRequests : List( ) from $repository.findActiveRequestsByEmployee( $user.getValue() ) # call to repository
eval( $activeRequests.size() > 0 )
then
System.err.println(' You have active requests: ' + ((Request)$activeRequests.get(0)).getTitle);
insert(Boolean.TRUE);
end
In this rule I try to access repository and get active requests for current user. Rule compiles and executes without any exceptions or warnings. In debug mode it can be seen that repository returns non empty list and I expect to see console message 'You have active requests' but this doesn't happen. I think the problem is in this line
$activeRequests : List( ) from $repository.findActiveRequestsByEmployee( $user.getValue() )
because this rule works fine
rule "check that no previously submitted requests exist"
when
$user : UserFormField( name == 'employeeId', value != null )
$repository : Repository( )
eval( $repository.findActiveRequestsByEmployee($user.getValue()).size() > 0 )
then
System.err.println(' You have active requests !' );
insert(Boolean.TRUE);
end
So could someone point me how to solve this problem?
Thanks!

I was helped to find a solution. I should use from collect expression instead simple from to bundle facts into collection :
$activeRequests : ArrayList() from collect ( Request() from $repository.findActiveRequestsByEmployee( $user.getValue() ) )

You have to distinguish (i.e., read the fine print in the
documentation) between "from" and "from collect". If you want the rule
to fire individually for each collection element produced by the
expression after "from", then use "from". If, however, you want to
have it all bundled into a collection you must used "from collect".
$activeRequests : ArrayList() from collect ( Request() from
$repository.findActiveRequestsByEmployee( $user.getValue() ) )
Note that the separate eval isn't necessary. You can put this
constraint into the ArrayList pattern:
ArrayList( size > 0 )

Related

Drools does not see the rules and returns null as a result

I have such code:
StatefulKnowledgeSession kSession = getKnowledgeBase().newStatefulKnowledgeSession();
this.insertFactsToWorkingMemory(inputCollection, kSession);
kSession.fireAllRules(new NotificationRuleNameFilter(name));
What insertFactsToWorkingMemory does is it takes object attributes and simply does WorkingMemory.insert(fact).
The rules are stored in .drl file and looks like:
rule "USER.PASSWORD_RENEW"
when
$config : UserSettings ( )
eval( true )
then
DroolsNotificationResult fact0 = new DroolsNotificationResult();
fact0.setBusinessRulePassed( true );
insert(fact0 );
end
The name of the rule and name passed in NotificationRuleNameFilter(name) match perfectly. Any clues?

Gravity Forms - Compare value against another field

Hoping someone can shed some light on this. I have a registration form setup in Gravity Forms for the registration of students. According to law a students guardian/parent needs to give consent for students under the age of 18. I have setup a conditional "Guardian/Parent" email field that only shows if the student is under the age of 18.
So X2 email fields are present in the form, one for the student and one for the guardian/parent. Once the forms is submitted, the activation mail is sent only to the guardian email address.
My problem is that at the moment the same email address can be pout in both the guardian/parent and student email. I would like to validate the 2 email fields and ensure that they are not the same.
I tried the following, but it has no effect at all.
add_filter( 'gform_field_validation_12_3', function ( $result, $value, $form, $field ) {
$master = rgpost( 'input_11' );
if ( $result['is_valid'] && $value == $master ) {
$result['is_valid'] = false;
$result['message'] = 'Please enter a different email.';
}
return $result;
}, 10, 4 );
The "12" in "gform_field_validation_12_3" represent my form_id and the "3" represents the guardian/parent field_id
The "11" in "$master = rgpost( 'input_11' );" represents my student email field_id
It simple does not validate the fields and submits the form even though I have the same email in both fields....
If email confirmation is enabled, you'll want to change this line:
if ( $result['is_valid'] && $value == $master ) {
to this:
if ( $result['is_valid'] && $value[0] == $master ) {
The issue is that when email confirmation is enabled, the $value is an array not a string. You can just get the first value from the array and it should work as expected.
If you don't want to fuss with having to know all of this, feel free to use this snippet I just wrote. It will also handle multiple fields and multiple groups of "unique" fields.
http://gravitywiz.com/gravity-forms-require-unique-values-for-different-fields/

OTRS PostMasterMailBox.pl not a scalar reference

I have just upgraded OTRS from 3 to 3.3. Before we retrieved emails from a mailbox, but it's not working now, the credentials has been verified multiple times and for all I can understand it connects just fine. We have not changed anything in the files, so we aren't quite sure what is up.
The error is:
"Not a SCALAR reference at /usr/share/perl15/Mail/IMAPClient.pm line 419"
This is the snippet of IMapClient.pm:419:
# give caller control of args to start_SSL if desired
my #sslargs =
( $self->Starttls and ref( $self->Starttls ) eq "ARRAY" )
? ( #${ $self->Starttls } )
: ( Timeout => 30 );
unless ( $ioclass->start_SSL( $sock, #sslargs ) ) {
$self->LastError( "Unable to start TLS: " . $ioclass->errstr );
return undef;
}
Edit: We had to do quick downgrade and that fixed the problem entirely, so I wonder if it's a bug in OTRS?
Have you checked the installed Perl Modules using otrs.CheckModules.pl?

Drools updating same object at the same time

I have two .drl files:
.dlr file one
rule "Lower Elementary Level"
no-loop
when
$m: MockBean ( overAllScore >= 40.51 && overAllScore < 60.76 )
$s : StudentMockBean()
then
$s.setKnowledgeLevel( "Lower Elementary Level" );
update( $s );
end
// some other condition
.drl file two
rule "Concept Lower Elementary Level"
no-loop
when
$m: MockBean ( mockOneScore >= 40.51 && mockOneScore < 60.76 )
$s : StudentMockBean()
then
$s.setMockOneKnowledgeLevel( "Lower Elementary Level" );
update( $s );
end
// some other condition
I'm reading both of them through this:
...
for( String fileName : aRuleFileName )
{
kbuilder.add( ResourceFactory.newClassPathResource( fileName, getClass() ), ResourceType.DRL );
}
// get error
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages( kbuilder.getKnowledgePackages() );
return kbase;
I fired both rules and both .drl file met the condition but they are updating same object.
My question is why does my web app keep on loading infinitely?
You are having an infinite loop caused by the combination of your rules.
I.e. rule A activates -> rule A fires -> modifies $s -> rule B activates -> rule B fires -> modifies $s -> rule A activates -> rule A fires -> modifies $s -> rule B activates -> rule B fires -> ...
no-loop is not enough solution for this situation.
For a better explanation on what's going on and possible ways to solve your problem please read this blog entry.
Hope it helps,

Anti Sql injection Library C# Asp.NET

Can anyone suggest such library for Asp.NET 1.1 ?
Thanks.
There are many to choose from, but in all honesty, your best tool is education. Knowing how to prevent it yourself. The tools built into the normal Framework class library are perfectly adequate if used properly.
Simply using parameterized queries and/or stored procedures for every database call is your best prevention.
However, that said, we do use the Microsoft.Practices.EnterpriseLibrary.Data classes provided with the Microsoft Patterns and Practices library. The ones we use are a bit outdated, but still do the job nicely. They provide some injection protection and also simplify data access. But they are not the only, nor necessarily best tool for the job.
More up-to-date information about the current Patterns and Practices library can be found here.
Link to Anti-Injection SQL
<?PHP
FUNCTION anti_injection( $user, $pass ) {
// We'll first get rid of any special characters using a simple regex statement.
// After that, we'll get rid of any SQL command words using a string replacment.
$banlist = ARRAY (
"insert", "select", "update", "delete", "distinct", "having", "truncate", "replace",
"handler", "like", " as ", "or ", "procedure", "limit", "order by", "group by", "asc", "desc"
);
// ---------------------------------------------
IF ( EREGI ( "[a-zA-Z0-9]+", $user ) ) {
$user = TRIM ( STR_REPLACE ( $banlist, '', STRTOLOWER ( $user ) ) );
} ELSE {
$user = NULL;
}
// ---------------------------------------------
// Now to make sure the given password is an alphanumerical string
// devoid of any special characters. strtolower() is being used
// because unfortunately, str_ireplace() only works with PHP5.
IF ( EREGI ( "[a-zA-Z0-9]+", $pass ) ) {
$pass = TRIM ( STR_REPLACE ( $banlist, '', STRTOLOWER ( $pass ) ) );
} ELSE {
$pass = NULL;
}
// ---------------------------------------------
// Now to make an array so we can dump these variables into the SQL query.
// If either user or pass is NULL (because of inclusion of illegal characters),
// the whole script will stop dead in its tracks.
$array = ARRAY ( 'user' => $user, 'pass' => $pass );
// ---------------------------------------------
IF ( IN_ARRAY ( NULL, $array ) ) {
DIE ( 'Invalid use of login and/or password. Please use a normal method.' );
} ELSE {
RETURN $array;
}
}
[1]: http://psoug.org/snippet/PHP-Anti-SQL-Injection-Function_18.htm
[1]: http://psoug.org/snippet/PHP-Anti-SQL-Injection-Function_18.htm