Currently I am quite happy.
This was easier as expected. When I first took a look at the JBoss Drools
Website I just got the impression, that this could be something cool, but I did
not get the point where to start? But as I said this is not the first time I am
using Drools. So I have been there and after some internet research I found
multiple examples to get some small examples running.
Enough gibberish let's start to check out other things about rules. So what I did not like about the previous rule and test was that we have to set the limit value in the test as well as in the rule. Normally such a value should be configurable, so it has to be set. Therefore, we can use global variables in Drools. Taking a look at the documentation at http://docs.jboss.org/drools/release/5.5.0.Final/drools-expert-docs/html/ch04.html#d0e4569 you get the idea behind global variabless and also some possibilities to misuse them :-).
global Double ALERTVALUE
rule "Critical value"
when
$v : SensorValue ( value > ALERTVALUE)
then
System.err.println("Critical sensor value");
end
No we can inject the value of alertValue into the rule, by using the setGlobal method of our session.
ksession.setGlobal("ALERTVALUE", 50.0);
When testing this rule, I also tried double and int as data types, as for example suggested by Jeremy, other books and some blogs. For me it did not work. I do not know why, but I got a parsing exception (unknown class).
Another thing is that we can bind variables:
rule "Critical value"
when
SensorValue ($id : sensorId)
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value in " + $id);
end
As you can see, it is possible to bind the sensor id to the variable §id and use it in the consequence. This rule shows another interesting thing about rules. When firing rules, the number of fired rules is returned as result of the method call. When using this rule, I got 10000 fired rules, but I only inserted 100 sensor values. The reason for this behavior is the cross product which is the result of the join. So instead of writing rules this way, the size of the cross product should be minimized.
global Double alertValue
rule "Critical value"
when
$v : SensorValue ( value > alertValue, $id : sensorId )
then
System.err.println("Critical sensor value in " + $id);
end
Another possibility is to use the getter of the bound object.
System.err.println("Critical sensor value in " +
$v.getSensorId());
Well, there is so much more about rules and their configuration. I will extend this post in the future, but there are other things to explore, for example decision tables.
Donnerstag, 23. Mai 2013
Drools Post 2 - The first Drool rule
I said, I will use Eclipse as IDE (or more precisely I will use Spring Tool Suite (STS) because I am using Spring quite often). Besides, Maven is required. Now lets start.
I just installed the JBoss Drools Plugin using the update site (http://download.jboss.org/drools/release/5.5.0.Final/org.drools.updatesite/). As you can see I am using 5.5.0.Final and not 6.0.0 because currently it has BETA status. Also there seems to be some problems when using Java 7, because the plugin is not working with compiled classes of the newest Java version.
After the installation of the plugin there should be some new possibilities. For example when you create a new file in your project, it should be possible to select Drools resources.
Now lets use on of these new possibilites. Lets create a new "Drools Project". I named it "drools-playground". I hate if some framework or library requires the creation of a project. Perhaps I want to use different frameworks or tools within one project... but lets see. We have to create a new Drools Runtime (seems to be some kind of library folder). After this is done we have our project. I just added the Spring nature (which works fine), but after I tried to add a Maven nature to the project nothing works :) - or perhaps I just have to wait.
It seems that Jeremy (from the book) had the same idea, so instead of creating a Drools Project, he creates a maven project from the scratch. I think, this is what I should have done from the beginning.
So lets do it... for me its always interesting which artifacts are required to get started, so I will post them here. Remember this is just to get started with drools:
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools.version}</version>
</dependency>
I use a property to set the version of drools. Just to make it complete, here is it:
<properties>
<drools.version>5.5.0.Final</drools.version>
</properties>
This is more the way I like it. So whats next, we should start with a small example right.So what do I want to do... well because I am doing lots of stuff in production industry lets use an example from this domain. I want to monitor sensor values. So just a simple rule:
Finally I have to classes SensorValue and SensorSimulator. A sensor value has a timestamp, a value and an id. Just to make it a little bit more interesting the type of the value is generic. The sensor simulator simple creates a sensor value each time his method nextValue() is called. After I cleanup my stuff I will upload the source code, so if anyone out there reads this and wants to use the produced stuff feel free :-).
package net.meisen.sensor
import net.meisen.sensor.simulation.SensorValue
rule "Critical value"
when
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value state.");
end
That was very easy. The rule is formulated using the MVFLEX Expresison Language. It consists of a package name, the required imports (in my case the POJO) and the rules. A rule contains a when part and a then part.
public class RuleTest {
private BasicSensorSimulator<Double> simulator;
private StatefulKnowledgeSession ksession;
@Before
public void init() {
simulator = new BasicSensorSimulator<Double>();
simulator.setRange(new DoubleRange(51.0, 100.0));
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("/rules
/sensor_value_rule.drl", SensorValue.class),
ResourceType.DRL);
if (kbuilder.hasErrors()) {
System.err.println(kbuilder.getErrors().toString());
fail();
}
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.
getKnowledgePackages());
ksession = kbase.newStatefulKnowledgeSession();
}
@Test
public void testRule() {
ksession.insert(simulator.nextValue());
ksession.fireAllRules();
ksession.dispose();
}
Very simple, but it does what it has to do. I get the expected warning:
Critical sensor value state.
What have I done? First I created a KnowledgeBuilder, which is responsible, as far as I understand, for loading and transforming the rules, so that the knowlege packages become available. These packages are used to create the knowledge base or more precisely to initializes it. Finally, this knowledge base can provide us with session. One important thing is that, in the example, I am using a stateful session. In contradiction to a stateless session such a session remembers changes when rules are fired and checks if such a change result in new evaluation results for already checked rules.
During the test I just insert some data into the session and trigger the rule engine to fire the different rules. Firing a rule means to check if the conditions are fulfilled and if something has to be done.As Jeremy points out: "Whenever you work with a session, it's important to always remember to use the dispose() function to dispose of it when you're done. If you don't, the garbage collector won't be able to free up the resources for you, and that means problems."
I just installed the JBoss Drools Plugin using the update site (http://download.jboss.org/drools/release/5.5.0.Final/org.drools.updatesite/). As you can see I am using 5.5.0.Final and not 6.0.0 because currently it has BETA status. Also there seems to be some problems when using Java 7, because the plugin is not working with compiled classes of the newest Java version.
After the installation of the plugin there should be some new possibilities. For example when you create a new file in your project, it should be possible to select Drools resources.
Now lets use on of these new possibilites. Lets create a new "Drools Project". I named it "drools-playground". I hate if some framework or library requires the creation of a project. Perhaps I want to use different frameworks or tools within one project... but lets see. We have to create a new Drools Runtime (seems to be some kind of library folder). After this is done we have our project. I just added the Spring nature (which works fine), but after I tried to add a Maven nature to the project nothing works :) - or perhaps I just have to wait.
It seems that Jeremy (from the book) had the same idea, so instead of creating a Drools Project, he creates a maven project from the scratch. I think, this is what I should have done from the beginning.
So lets do it... for me its always interesting which artifacts are required to get started, so I will post them here. Remember this is just to get started with drools:
<!-- Drools -->
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools.version}</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>knowledge-api</artifactId>
<version>${drools.version}</version>
</dependency>
I use a property to set the version of drools. Just to make it complete, here is it:
<properties>
<drools.version>5.5.0.Final</drools.version>
</properties>
This is more the way I like it. So whats next, we should start with a small example right.So what do I want to do... well because I am doing lots of stuff in production industry lets use an example from this domain. I want to monitor sensor values. So just a simple rule:
- when a sensor measures a value greater than 50.0 then show a warning message
Finally I have to classes SensorValue and SensorSimulator. A sensor value has a timestamp, a value and an id. Just to make it a little bit more interesting the type of the value is generic. The sensor simulator simple creates a sensor value each time his method nextValue() is called. After I cleanup my stuff I will upload the source code, so if anyone out there reads this and wants to use the produced stuff feel free :-).
A first rule
Now the interesting part begins. After doing the necessary POJO and programming stuff, I want to formulate the rule. First a so called DRL file has to be generated. This can either be done in the simple way, by using the Eclipse Text Editor or by using the more comfortable Eclipse PlugIn. Because I installed the plugin and I wanted to see what this plugin can do, I will use this method. I also created a folder src/main/rules to store my rules at this location. So here is the rule:package net.meisen.sensor
import net.meisen.sensor.simulation.SensorValue
rule "Critical value"
when
$v : SensorValue ( value >50.0 )
then
System.err.println("Critical sensor value state.");
end
That was very easy. The rule is formulated using the MVFLEX Expresison Language. It consists of a package name, the required imports (in my case the POJO) and the rules. A rule contains a when part and a then part.
Getting it to work
Now to test my little rule, I want to use a test. So I have an initialization and the tests.public class RuleTest {
private BasicSensorSimulator<Double> simulator;
private StatefulKnowledgeSession ksession;
@Before
public void init() {
simulator = new BasicSensorSimulator<Double>();
simulator.setRange(new DoubleRange(51.0, 100.0));
KnowledgeBuilder kbuilder =
KnowledgeBuilderFactory.newKnowledgeBuilder();
kbuilder.add(ResourceFactory.newClassPathResource("/rules
/sensor_value_rule.drl", SensorValue.class),
ResourceType.DRL);
if (kbuilder.hasErrors()) {
System.err.println(kbuilder.getErrors().toString());
fail();
}
KnowledgeBase kbase =
KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.
getKnowledgePackages());
ksession = kbase.newStatefulKnowledgeSession();
}
@Test
public void testRule() {
ksession.insert(simulator.nextValue());
ksession.fireAllRules();
ksession.dispose();
}
Very simple, but it does what it has to do. I get the expected warning:
Critical sensor value state.
What have I done? First I created a KnowledgeBuilder, which is responsible, as far as I understand, for loading and transforming the rules, so that the knowlege packages become available. These packages are used to create the knowledge base or more precisely to initializes it. Finally, this knowledge base can provide us with session. One important thing is that, in the example, I am using a stateful session. In contradiction to a stateless session such a session remembers changes when rules are fired and checks if such a change result in new evaluation results for already checked rules.
During the test I just insert some data into the session and trigger the rule engine to fire the different rules. Firing a rule means to check if the conditions are fulfilled and if something has to be done.As Jeremy points out: "Whenever you work with a session, it's important to always remember to use the dispose() function to dispose of it when you're done. If you don't, the garbage collector won't be able to free up the resources for you, and that means problems."
Drools Post 1 - What is Drools
The website says Drools is
a Business Rule Management System, but well what is that. It also talks
about the Rete algorithm, which you can look up at wikipedia [Wikipedia:Rete_algorithm].
As I said I bought a book to get the answers. Jeremy Ary says that
"Drools is a collection of tools which allow us to separate and reason
over logic and data found within businss processes". He continues that this
is quite not the answer someone wants to get - just from my point of
view - he is right :-).
So one important thing that we have are rules. And well we want to use these rules to build a rule-driven system. More precisely we want to tell our system how to react if some conditions are fulfilled. For example throw an event, inform someone or just shutdown. If a condition is fulfilled depends on the data, the facts of the world. Sometime the knowledge of a new fact results in another fact, that results in new fulfilled conditions.
So summarized, Drools enables us to define rules that are executed by the rule engine. The rule itself is not part of the code... but it uses facts or data that is derived from it. So the logic is extracted from our code, as long as it is rule-oriented logic. Sounds nice. So lets get started...
So one important thing that we have are rules. And well we want to use these rules to build a rule-driven system. More precisely we want to tell our system how to react if some conditions are fulfilled. For example throw an event, inform someone or just shutdown. If a condition is fulfilled depends on the data, the facts of the world. Sometime the knowledge of a new fact results in another fact, that results in new fulfilled conditions.
So summarized, Drools enables us to define rules that are executed by the rule engine. The rule itself is not part of the code... but it uses facts or data that is derived from it. So the logic is extracted from our code, as long as it is rule-oriented logic. Sounds nice. So lets get started...
Drools - Getting started...
Just a few words at the beginning
Today, I want to start using Drools in a more professional way. I have used Drools in the past, for smaller projects and out of sheer curiosity, but I never tried to learn it from the scratch.A few minutes ago, I bought the ebook "Instant Drools Starter" by Jeremy Ary to get a better overview and a starting point. I hope the book deliveres :-). So I will update this post, and also prepare a presentation during my work. Perhaps I will upload it.
So what will I use:
- Spring Tool Suite (but I think Eclipse will do it)
- Maven for dependency management
- normally I am using Spring, but we will see
First post
So this will be my first post on this blog. Just to inform you, I am from Germany, so please be thoughtful when writing about my English. I promise you, I will give my best.
What can you expect? Well I am doing a lot of Java programming at work and at home. I started programming when I was ten (Turbo Pascal, QBasic). Later I changed to C, C++ and Visual Basic. And as you can expect after dealing with C++ and all its benefits and its bad things, I also started working with Java Version 1.
Now I am still using Java and C++, also C# and a lot of other stuff... but still I like Java and it's frameworks very much. So in this blog I will tell you what I am doing right now, which problems I am facing and how I solved them. Perhaps it is not always Java... but mostly.
I will use it as reference for myself, but I hope that you find answer to your questions and perhaps can provide additional knowledge.
What can you expect? Well I am doing a lot of Java programming at work and at home. I started programming when I was ten (Turbo Pascal, QBasic). Later I changed to C, C++ and Visual Basic. And as you can expect after dealing with C++ and all its benefits and its bad things, I also started working with Java Version 1.
Now I am still using Java and C++, also C# and a lot of other stuff... but still I like Java and it's frameworks very much. So in this blog I will tell you what I am doing right now, which problems I am facing and how I solved them. Perhaps it is not always Java... but mostly.
I will use it as reference for myself, but I hope that you find answer to your questions and perhaps can provide additional knowledge.
Abonnieren
Posts (Atom)