Allowing end users to modify rules file - drools

I have a set of rules for each of my user. Right now, these rules are setup in a file. But I want to allow my users to modify / add rules. The rules aren't that complicated. For instance, below are a couple of rules:
rule "Rule 1"
when
$order : OrderInfo(getOrderDate() < new Date(...)
then
$order.setReturnEligibility(false);
end
rule "Rule 2"
when
$item : ItemInfo( nonReturnableCategory.contains(getItemCategory().toLowerCase()) )
then
$item.setReturnEligibility(false);
end
rule "Rule 3"
when
$item : ItemInfo( isFinalSale())
then
$item.setReturnMethod(...);
end
I want to build a UI similar to Drools workbench. But this is for the end customer, so I want it to be a very simple, user-friendly UI. And I was planning to store the rules in a database.
I want to allow the users to add new rules and modify existing ones. For instance, if Rule 3 above was not available, the user will have a dropdown in the UI, where they can select the item categories which are not returnable. Or they can enable or disable any of the rules etc.
What I wanted to know is, what is the best way to maintain the rules? Should I just have the entire rules file as a string in DB with some sort of place holders, and modify the string as and when the user adds / updates the rules? I'm using Drools 6.2. I know the question is kind of vague, but I have no idea how / where to begin, so any suggestion is appreciated.
Thanks.

If modifying an existing rule means that only the constraint changes the "text with place holder" might be a good idea.
However, I would not store the entire DRL file as a DB entry. Probably a system where individual rules are stored as entities would work best. Attributes would be a name, the text, an "is selected" attribute etc.

Related

Drools: Recommended way to include multiple drl files, for breaking up business logic

I have an application I am trying to experiment with. The business rules I am trying to create are all related but it makes sense for me to group the logic by drl file. For example, I want to put information about customers in the customer.drl file. I want to put logic about the categories of product in the productCategory.drl file and purchases.drl. Finally, I'd like to have a fourth file summarizing my findings for a report.drl
I don't want to create entirely separate modules. I just want to split out the logic so that I can easily maintain the logic in the code. In effect, I'd like something like this:
src/main/resources/rules
customers.drl
purchases.drl
productCategory.drl
reports.drl
I want to be able to share the logic between the facts in a single KieSession, utilizing all the drl files. First, I want to insert customer facts, group them by demographics, then insert their purchase information and products purchased and categorize them. Finally, I want to aggegrate that data in a report by inserting the previously gathered facts to generate data from the reports.drl
Is the configuration, I'm showing a feasible way of doing it. I'm of course assuming that the KiesSession will pick all the drl files in the rules package if I use a classpath container.
Is this the right way?
Looking at the documentation, I can group related rules under the same package. It is one of the options available. So for my use case this works. According to the documentation, I can create a kmodule.xml, and indicate the package, use a classpath container and load the KieSession. If I use a default kmodule definition with no KieBase defined, it will use a default KieBase and load all the resources in the src/main/resources and its other subfolders and this works!

How to find how many rules are associated with a rule task in IBM ODM/Rule Designer 8.8.1?

I'm new to the IBM Rule Designer (8.8.1) and my team has inherited a project that contains numerous rule flows, subflows, rule/action tasks, etc. I'm attempting to document at the task (ie. rule flow node) level, but there are instances where 100+ rules are included in a rule task. Is there a way to query a rule task to quickly find the number of rules that are associated with a specific rule task? I couldn't find any query condition phrases or objects that appeared to say something like Find all business rules such that each business rule [is contained within <a rule task>].
Any ideas on how to accomplish that? Is there a way to turn the results from a list of rules into an integer count of rules?
Thanks for your help; please let me know if clarification is needed.
Short Answer: I don't think there is an easy way, but there is a way.
Using queries, I think the closest you can come is to find all rules in a rule package. It is common (and good) practice for the rule tasks to line up with rule packages, so that is often useful or good enough. If the rule selection specifies individual rules, queries probably won't help.
It is easy to go the other way -- to find which rule task(s) a rule appears in. Just right-click on a rule, either in the Rule Explorer view or the Rule Editor view, select 'Find Rule Dependencies' then select 'Ruleflows which may select this rule'. Not what you asked for, but often helpful.
Note: When you run a query or do any other search, the results appear in the Search view and the number of matches is included at the top. Be aware that this count may include the same rule more than once if it appears in multiple rule tasks.
What I would do to count the rules of a rule task that are specified individually is look at the source code for the rule flow. Open the ruleflow in the Ruleflow Editor and select the *.rfl tab. Scroll down or search to find the tag that you are interested in. You can turn on line numbering (right-click, Preferences, Show line numbers) and do the math yourself. Or you can select the tags from the , copy it to the clipboard, and paste it into another program that counts lines. You could use Excel, which automatically counts the number of items selected, or another editor, or even create empty file in Eclipse with line numbering on.

How to group Rules in drools and fire only particular Group rules?

I am building a rule Engine in which I want to group rules in such a way that for a particular fact drools will not check for all the rules instead it will check for the rule in a specific group.
Is it possible to implement?
Yes. It is possible to implement, you have to implement a process with the rules you want to apply to the specific group, then you can implement a rule like this:
rule "start process if ..."
when
// Fact in specific group?
then
kcontext.getKieRuntime().startProcess("ProcessName");
end
I would recommend you to follow the official drools tutorial, specially the lesson 4: https://nheron.gitbooks.io/droolsonboarding/content/gettingStarted/lesson_4__ruleflow.html
They teach you how to do this step by step.

Typo3 best practices - general variables

What is the best way to allow backend users to edit variables?
For example, I have a TYPO3 that sends out various e-Mail notifications and I want the backend users to be able to globally change the recipients. I started with template constants, until I found out, that backend users cannot edit the "template" module.
So what would be the best way to achieve this? I'm using Typo3 8.7.7
I would create a configuration record which can be edited by the backend users.
one way would be to include one file from fileadmin/ into the constants definition of typoscript. This file editors could change. But that could be a security risk, as the editors could define any constants.
the next option would be to define additional fields to the pages record, where these values could be set by any editor. In typoscript you access the field (maybe with slide = -1, so the value needs to be set just once)
another option: add these fields to a (special?) CE (ContentElement).
last option: use std CEs (e.g.HTML-content) at special pages or columns and use the content field (bodytext). (HTML-content has the advantage that the bodytext field is stored unmodified.)
Cleanest and leanest option would be option two (additional fields to table 'pages'). Option three and four are possible with pure typoscript, but you need to use CONTENT or RECORD object. If you use fix uids: remember that your editors might delete the CE and add a new CE with the same content (but another uid)
Addition:
As #Thomas-Löffler in his answer said:
you also can add a new kind of record/table, where an editor can insert or change the global values. Handling is like pages or tt_content. you can differ if your records are global (pid = 0, or special storage page) or dependent on page tree (rootpath), so you can have differnt values for different page subtrees.
I like Thomas‘ answer for providing a dedicated place to store the configuration option instead of putting it e.g. to pages because your configuration option is not bound to a page context.
Nonetheless for me personally it feels a bit odd to create a dedicated table for it. A table that would never hold more than one record.
That leads me to the conclusion that a key-value storage would be the right thing to use. Fortunately, TYPO3 ships System Registry. The only downside is that there‘s no interface for it so you‘d have to come up with your own forms to fill it. That‘s much easier if you go with Thomas‘ solution…
A clean and easy way is setting up a backend module with a form to set the email addresses.
Then you can grant the access right to a specific group or user and they are ready to go.

Run workflow over all entities to copy data from one field to another

I'm in a situation where i need to add a default value "blank" to my "Two Options" field. Since I cannot set a default value of "null" to an already created Two Options field, I though of creating a new custom field of type "Option Set" and add the same two options Yes/No in addition to setting the Default value to Unassigned.
I need to create a workflow that copies the old values choices into the new field. I understand that I can't simple equate the values of two fields of different type but I'm going to do that with Check conditions to set the new field value corresponding to the old field value.
I'm not sure how to run this workflow against all the existing records in my CRM online with no codes. Is that possible ?
Without using code or custom tools your best options are:
Do an advanced find, select all the records in the view and run the workflow - this will run the workflow against every record. You can view up to 250 records at a time (check personal settings to change this) so this might work for you.
Export all the data to Excel, make the change in Excel in bulk. Reimport the data. This way you don't need workflow at all.