<div dir="ltr">Hi Davide,<div><br></div><div>Thanks, I just wanted to get a grasp of the time frame we could expect (whether it is a month or half a year etc.) :) </div><div><br></div><div>A bit more about our use case: we have a <b>massive</b> old system, with basically all of the logic embedded into Java. We are in the process of refactoring and moving up-to-date Java technologies. We would like to introduce a rule engine so as to extract logic from the core of the application. Since we need to re-structure the whole back-end and persistence layer, we face a challenge with rules: as the object model changes, the rules have to change also, which simply would not be manageable. (Imagine something really crazy/complex here: 6-8-... levels of object hierarchy, grown most of the time organically during the last 15 years.) Deferring the introduction of the rule engine until the data model classes reach the final, ideal state is not something we can now afford, the rule engine and data model refactoring projects should be done in parallel, without the one paralyzing the other one... </div>
<div><br></div><div>Take the following as an example (from the manual). Say, you have Applicant class, with age and name fields: </div><div><br></div><div><div><font face="courier new, monospace">public class Applicant {<br>
</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> private String name;</font></div><div><font face="courier new, monospace"> private int age;</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">// getters/setters</font></div><div><font face="courier new, monospace">}</font></div></div><div><br></div><div>Then, you could have a simple rule, requiring, that name must be supplied:</div>
<div><br></div><div><div><font face="courier new, monospace">rule "Supplied a proper name"</font></div><div><font face="courier new, monospace">when</font></div><div><font face="courier new, monospace"> Applicant( name == null)</font></div>
<div><font face="courier new, monospace"> $a : Application()</font></div><div><font face="courier new, monospace">then</font></div><div><font face="courier new, monospace"> output.println("### RULE MATCH: Invalid application: No name specified!");</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> $a.setValid( false );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">end</font></div>
</div><div><br></div><div>But there is an issue: every single time you refactor / rename any field in your domain model, the rules are no longer valid. That is why we have a problem: we should start developing rules against a relatively fluid object model. Say Applicant.name is renamed to Applicant.fullName, then the existing rules are no longer valid. That is why I would like to have some sort of abstraction, since the rules do not really need to know the <i>exact </i>details of the underlying class. </div>
<div><br></div><div>As a demonstration of my idea, I managed to hack together a custom parameterizable operator, that calls the method where the annotation contains the same parameter as in the rule. With this approach, changes to the field names would no longer affect the rules. Again, I have to highlight, I don't think this should necessarily be implemented in the core engine. <b>What I am looking for is some kind of extension point allowing us to hook into the expression evaluation part of Drools</b>. (Instead of a custom operator, something, where we can access the object and the expression being resolved so that we can implement our custom logic for returning the value of the expression)</div>
<div><br></div><div>The rule now looks like this - note the custom satisfiesRule operation. The "Name of this Applicant" expression now abstracts away the name of the actual field (the second parameter is the operator for the test, please ignore it for now): <br>
</div><div><br></div><div><div><font face="courier new, monospace">rule "Supplied a proper name"</font></div><div><font face="courier new, monospace"> agenda-group "evaluate-application"</font></div>
<div><font face="courier new, monospace"> auto-focus true</font></div><div><font face="courier new, monospace">when</font></div><div><font face="courier new, monospace"> Applicant( this satisfiesRule[ "Name of this Applicant" , "is equal to" ] null )</font></div>
<div><font face="courier new, monospace"> $a : Application()</font></div><div><font face="courier new, monospace">then</font></div><div><font face="courier new, monospace"> output.println("### RULE MATCH: Invalid application: No name specified!");</font></div>
<div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace"> $a.setValid( false );</font></div><div><font face="courier new, monospace"><br></font></div><div><font face="courier new, monospace">end</font></div>
</div><div><br></div><div>The name is simply mapped by a custom annotation: </div><div><br></div><div><div><font face="courier new, monospace">public class Applicant {</font></div><div><font face="courier new, monospace"><br>
</font></div><div><font face="courier new, monospace"> private String name;</font></div><div><font face="courier new, monospace"> private int age;</font></div><div><font face="courier new, monospace"> </font></div>
<div><font face="courier new, monospace"> @MyBusinessExpression("Name of this Applicant")</font></div><div><font face="courier new, monospace"> public String getName() {</font></div><div><font face="courier new, monospace"> return name;</font></div>
<div><font face="courier new, monospace"> }</font></div><div><font face="courier new, monospace">// getters/setters</font></div><div><font face="courier new, monospace">}</font></div></div><div><br></div><div><br></div>
<div>I think having a level of abstraction between the rules and the data model would not only be useful for de-coupling, but also can make rule authoring easier for the business users. The custom operator (please see attachment) is a kind of hacky workaround, but demonstrates how something similar could be achieved at run time (without using DSL or any other rule transformation). </div>
<div><br></div><div>Please let me know what you think. :)</div><div><br></div><div>Cheers,</div><div>Peter</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div>
<br></div></div><div class="gmail_extra"><br><br><div class="gmail_quote">2014-06-02 11:54 GMT+02:00 Davide Sottara <span dir="ltr"><<a href="mailto:dsotty@gmail.com" target="_blank">dsotty@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div>I can't guarantee a public date.. as a
community member, I work on a "best effort" basis...<br>
I'll try to do it before the end of the month, though. <br>
For now, as a workaround, I would create derived getter/setter
pairs that expose the desired<br>
computations. A concrete example of what you are trying to do
exactly would also be helpful,<br>
feel free to contact me privately if you can't share your code
here<br>
Best<span class="HOEnZb"><font color="#888888"><br>
Davide</font></span><div><div class="h5"><br>
<br>
On 05/28/2014 10:08 AM, Péter Gergely, Horváth wrote:<br>
</div></div></div><div><div class="h5">
<blockquote type="cite">
<div dir="ltr">Thanks for the explanation, I was a bit confused
because of the terminology; "virtual" is not mentioned in the
docs. ;)
<div><br>
</div>
<div>Is there any plan for the public release of Trait property
binding to a nested path? We would definitely need something
like that in our environment. Or do you see any way we could
hook into the property look-up mechanism? Based on what I
know, I don't see any official extension point for that.</div>
<div><br>
</div>
<div>My only idea would be using some Java proxy voodoo-magic to
wrap objects before they are inserted to the session, but my
gut feeling is that it would be a way to debug hell... </div>
<div><br>
</div>
<div>
What do you think?</div>
<div><br>
</div>
<div>Cheers,</div>
<div>Peter</div>
<div><br>
</div>
</div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">2014-05-27 19:42 GMT+02:00 Davide
Sottara <span dir="ltr"><<a href="mailto:dsotty@gmail.com" target="_blank">dsotty@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000">
<div>Consider that a trait is an interface applied to some
class. In the context of the pair:<br>
A "hard" field is a property (get/set) exposed by the
interface AND the underlying class<br>
A "soft" (or "virtual") field is a property exposed by
the interface BUT NOT by the underlying class<br>
A "hidden" field is a field of the underlying class NOT
exposed by the interface<br>
<br>
Hard and Soft fields can be accessed using the
interface, hidden fields are accessible using the
map-like<br>
construct fields[ "fieldName" ].<br>
<br>
This said,<br>
the mapping is by default done using the property name
and (then) the property type.<br>
However, this mapping can be decoupled using the
annotation @Alias() on either the class OR the trait.<br>
E.g.<br>
declare Core <br>
name : String @Alias( "any-Id-or-even-an-IRI-here" )<br>
end <br>
<br>
declare trait SomeTrait<br>
label : String @Alias( "..." ) // if two "aliases"
match, this will be considered a hard field<br>
end<br>
<br>
The "accessor", i.e. the ability to bind a trait
property to a (possibly deeply) nested path is what I'm
working<br>
on these days, I have the same requirement from another
urgent use case<br>
<br>
For the time being, you can probably create a "shortcut"
accessor pair in your implementation class, <br>
to execute the complex expression, and @Alias it to the
trait field.<br>
<br>
Please let me know if you find any issue/bugs and any
feature request you may have!<br>
Best<span><font color="#888888"><br>
Davide</font></span>
<div>
<div><br>
<br>
<br>
On 05/27/2014 07:57 AM, Horváth Péter Gergely wrote:<br>
</div>
</div>
</div>
<div>
<div>
<blockquote type="cite">
<div dir="ltr">Hi Davide,
<div><br>
</div>
<div>Drools trait functionality is one of the
powerful concepts which makes Drools a good
candidate for the project. So keep up the good
work! :) However I'm not sure if its current
level of flexibility would be sufficient for our
use case. I've checked the documentation, but
haven't really found the term virtual field --
could you please elaborate on this?</div>
<div><br>
</div>
<div>Do you think we could somehow hook into the
evaluation of the aliases or the "fields" Map?
Sometimes you would need slightly more than
merely aliasing fields to something else; e.g.
calculating values for the purpose of rule
processing or extracting a value from a more
complex object tree etc. Citing the example --
GoldenCustomer( fields[ "age" ] > 18 ) --
being able to get a reference to the target
object and the field map expression "age" would
be quite close to what I imagined. Our custom
code could then perform the appropriate
translation and return the requested value,
hiding the fact whether "age" is an actual field
in the Customer object itself/retrieved from an
encapsulated complex object e.g. replacing
expression
"customer.personalInformation.birthData.age"/calculated
on the flight. </div>
<div><br>
</div>
<div>What do you think?</div>
<div><br>
</div>
<div>Cheers,</div>
<div>Peter</div>
<div><br>
</div>
</div>
<div class="gmail_extra"><br>
<br>
<div class="gmail_quote">2014-05-26 17:58
GMT+02:00 Davide Sottara <span dir="ltr"><<a href="mailto:dsotty@gmail.com" target="_blank">dsotty@gmail.com</a>></span>:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">We are working on the
trait framework for cases like this.
Essentially,<br>
it allows to use<br>
interfaces when writing rules AND to inject
the interfaces dynamically<br>
at runtime,<br>
at the instance level. It relies on
transparent proxies which wrap the<br>
data classes<br>
and implement the required interfaces. A
simple field aliasing mechanism<br>
is provided<br>
(work in progress). For more complex
transformations, "virtual" fields<br>
can be added.<br>
See section 7.7.8 of the manual for more
details and let me know if it<br>
can help<br>
with your use case.<br>
Best,<br>
Davide<br>
<div>
<div><br>
On 05/26/2014 09:55 AM, Wolfgang Laun
wrote:<br>
> Even a relatively sophisticated
transformation would be easier to
implement<br>
> and most certainly safer from changes
in the unstable Drools API than some<br>
> hook-and-intercept mechanism built
into Drools.<br>
><br>
> Notice that violent structural
departure of the model the BUs see from
what<br>
> you call "persistence model" might
make it impossible for the BUs to come<br>
> up with rules that can be transformed
to match the other model at all;<br>
> if it is possible, rules might still
incur a heavy performance penalty.<br>
><br>
> It is (IMHO) a myth that "Rules" is a
foolproof way of establishing<br>
> business logic<br>
> independent from the data model and
application environment with which<br>
> this logic should be able to
cooperate. As long as everything is kept
in the<br>
> abstract (i.e., formulated in terms
of mathematics) it will look good, but<br>
> any implementation may throw a
spanner in the works, or worse.<br>
><br>
> -W<br>
><br>
> On 26/05/2014, Péter Gergely, Horváth
<<a href="mailto:h.peter@mailbox.hu" target="_blank">h.peter@mailbox.hu</a>>
wrote:<br>
>> Hi Wolfgang,<br>
>><br>
>> Thank you for your input. You are
right that some of the cases could simply<br>
>> be covered by regexp-replace, but
I'm afraid, not all of them. Interfaces<br>
>> could also help, but we have a
requirement that the business rules should<br>
>> not be tightly coupled to the
underlying persistence model. (I
understand<br>
>> that some might say this is not
ideal, but that is our current situation)<br>
>><br>
>> I am wondering whether it is
possible to hook into Drools engine and<br>
>> intercept field value reference
expression evaluations in run time (e.g if<br>
>> "foo.bars" is used in an
expression, we could return "foo.barList")
? By<br>
>> injecting some custom code, we
could make the necessary decisions and<br>
>> extract the proper value from an
object. Unfortunately these parts of<br>
>> Drools are pretty much
undocumented.<br>
>><br>
>> Regards,<br>
>> Peter<br>
>><br>
>><br>
>><br>
>> 2014-05-26 13:57 GMT+02:00
Wolfgang Laun <<a href="mailto:wolfgang.laun@gmail.com" target="_blank">wolfgang.laun@gmail.com</a>>:<br>
>><br>
>>> What you describe can be done
with /bin/sed.<br>
>>><br>
>>> Notice that the DSL processor
doesn't require you to translate entire<br>
>>> patterns; there is a
mechanism for translating "keywords",
which is<br>
>>> just arbitrary tokens to
whatever replacement text.<br>
>>><br>
>>> If a "bar" must be translated
to a "barList" in the context of a class<br>
>>> "Foo" but not in any other
context, a more sophisticated translation<br>
>>> is required in any case (with
/bin/sed still being sufficient if<br>
>>> patterns aren't split across
lines).<br>
>>><br>
>>> Some say that good design
makes use of Interfaces, which leaves room<br>
>>> for actual implementations
being changed as long as the interfaces
are<br>
>>> implemented. Here, note that
rules can be written against interface<br>
>>> types.<br>
>>><br>
>>> -W<br>
>>><br>
>>><br>
>>> On 26/05/2014, Péter Gergely,
Horváth <<a href="mailto:h.peter@mailbox.hu" target="_blank">h.peter@mailbox.hu</a>>
wrote:<br>
>>>> Hi All,<br>
>>>><br>
>>>> We are evaluating Drools
6 for our use case, and face challenges
where<br>
>>>> we<br>
>>>> would need some ideas
from more experienced users of Drools.<br>
>>>><br>
>>>> We have an application
with a massive code base and a large
number of<br>
>>> model<br>
>>>> (entity) classes. We are
in the process of moving away from
inherited<br>
>>>> legacy technologies and
refactoring the old code base. As a part
of<br>
>>>> this<br>
>>>> work we would like
extract some of the hard-coded business
logic to<br>
>>>> external rules, that is
why we are looking at Drools as a
potential<br>
>>>> solution.<br>
>>>><br>
>>>> What we would like to
have is some kind of abstraction or
mapping<br>
>>>> between<br>
>>>> actual entities and rules
the business users can define so that they
do<br>
>>> not<br>
>>>> have to know the _exact_
details of the data model (field names,<br>
>>>> precise<br>
>>>> relations etc). This
would be important for us so that we can
refactor<br>
>>> the<br>
>>>> old model classes without
affecting business rules; also it would
make<br>
>>> life<br>
>>>> easier for the business
users. While IDE support might make
refactoring<br>
>>>> easier, we definitely
want to have a separation between rules
and<br>
>>> entities.<br>
>>>> Given our situation,
writing and maintaining "stable"
wrapper/adapter<br>
>>>> classes for the sole
purpose of rule processing is out of
question. I<br>
>>> have<br>
>>>> checked the documentation
of Drools DSL support and for me it seems
to<br>
>>>> be<br>
>>>> overkill for our use
case: we do not really need a custom
language, but<br>
>>>> simply an abstraction
between rules and the data model classes.<br>
>>>><br>
>>>> What I could imagine is a
piece of code, (a custom property
resolver? -<br>
>>> no<br>
>>>> sure how it is called)
which maps property expressions to actual<br>
>>> properties<br>
>>>> based on a custom
annotation on the entity class or
something like<br>
>>>> that,<br>
>>> so<br>
>>>> that a rule containing
"Foo.bars" expression does not have to
change<br>
>>>> even<br>
>>>> if we decide to rename
"Foo.bars" to "Foo.barList" in the model<br>
>>>> classes.<br>
>>>> (This was just a simple
example of a potential use cases)<br>
>>>><br>
>>>> Could you please share
your thoughts on this topic and point me
into<br>
>>>> the<br>
>>>> right direction?<br>
>>>><br>
>>>> Thanks,<br>
>>>> Peter<br>
>>>><br>
>>>
_______________________________________________<br>
>>> rules-users mailing list<br>
>>> <a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
>>> <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
>>><br>
>
_______________________________________________<br>
> rules-users mailing list<br>
> <a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
> <a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
><br>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</div>
</div>
</blockquote>
</div>
<br>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
rules-users mailing list
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a></pre>
</blockquote>
<br>
</div>
</div>
</div>
<br>
_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br>
</blockquote>
</div>
<br>
</div>
<br>
<fieldset></fieldset>
<br>
<pre>_______________________________________________
rules-users mailing list
<a href="mailto:rules-users@lists.jboss.org" target="_blank">rules-users@lists.jboss.org</a>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a></pre>
</blockquote>
<br>
</div></div></div>
<br>_______________________________________________<br>
rules-users mailing list<br>
<a href="mailto:rules-users@lists.jboss.org">rules-users@lists.jboss.org</a><br>
<a href="https://lists.jboss.org/mailman/listinfo/rules-users" target="_blank">https://lists.jboss.org/mailman/listinfo/rules-users</a><br></blockquote></div><br></div>