JBoss.orgCommunity Documentation

Chapter 2. Release Notes

2.1. What is New and Noteworthy in Drools 6.3.0
2.1.1. Real Time Validation and Verification for the Decision Tables
2.1.2. Improved DRL Editor
2.1.3. Browsing graphs of objects with OOPath
2.2. New and Noteworthy in KIE Workbench 6.3.0
2.2.1. Generation of JPA enabled Data Models
2.2.2. Data Set Authoring
2.3. What is New and Noteworthy in Drools 6.2.0
2.3.1. Propagation modes
2.4. New and Noteworthy in KIE Workbench 6.2.0
2.4.1. Download Repository or Part of the Repository as a ZIP
2.4.2. Project Editor permissions
2.4.3. Unify validation style in Guided Decision Table Wizard.
2.4.4. Improved Wizards
2.4.5. Consistent behaviour of XLS, Guided Decision Tables and Guided Templates
2.4.6. Improved Metadata Tab
2.4.7. Improved Data Objects Editor
2.4.8. Execution Server Management UI
2.4.9. Social Activities
2.4.10. Contributors Dashboard
2.4.11. Package selector
2.4.12. Improved visual consistency
2.4.13. Guided Decision Tree Editor
2.4.14. Create Repository Wizard
2.4.15. Repository Structure Screen
2.5. New and Noteworthy in Integration 6.2.0
2.5.1. KIE Execution Server
2.6. What is New and Noteworthy in Drools 6.1.0
2.6.1. JMX support for KieScanner
2.7. New and Noteworthy in KIE Workbench 6.1.0
2.7.1. Data Modeler - round trip and source code preservation
2.7.2. Data Modeler - improved annotations
2.7.3. Standardization of the display of tabular data
2.7.4. Generation of modify(x) {...} blocks
2.8. New and Noteworthy in KIE API 6.0.0
2.8.1. New KIE name
2.8.2. Maven aligned projects and modules and Maven Deployment
2.8.3. Configuration and convention based projects
2.8.4. KieBase Inclusion
2.8.5. KieModules, KieContainer and KIE-CI
2.8.6. KieScanner
2.8.7. Hierarchical ClassLoader
2.8.8. Legacy API Adapter
2.8.9. KIE Documentation
2.9. What is New and Noteworthy in Drools 6.0.0
2.9.1. PHREAK - Lazy rule matching algorithm
2.9.2. Automatically firing timed rule in passive mode
2.9.3. Expression Timers
2.9.4. RuleFlowGroups and AgendaGroups are merged
2.10. New and Noteworthy in KIE Workbench 6.0.0
2.11. New and Noteworthy in Integration 6.0.0
2.11.1. CDI
2.11.2. Spring
2.11.3. Aries Blueprints
2.11.4. OSGi Ready

When the field of a fact is a collection it is possible to bind and reason over all the items in that collection on by one using the from keyword. Nevertheless, when it is required to browse a graph of object the extensive use of the from conditional element may result in a verbose and cubersome syntax like in the following example:


In this example it has been assumed to use a domain model consisting of a Student who has a Plan of study: a Plan can have zero or more Exams and an Exam zero or more Grades. Note that only the root object of the graph (the Student in this case) needs to be in the working memory in order to make this works.

By borrowing ideas from XPath, this syntax can be made more succinct, as XPath has a compact notation for navigating through related elements while handling collections and filtering constraints. This XPath-inspired notation has been called OOPath since it is explictly intended to browse graph of objects. Using this notation the former example can be rewritten as it follows:


Formally, the core grammar of an OOPath expression can be defined in EBNF notation in this way.

OOPExpr = "/" OOPSegment { ( "/" | "." ) OOPSegment } ;
OOPSegment = [ID ( ":" | ":=" )] ID ["[" Number "]"] ["{" Constraints "}"];

In practice an OOPath expression has the following features.

  • It has to start with /.

  • It can dereference a single property of an object with the . operator

  • It can dereference a multiple property of an object using the / operator. If a collection is returned, it will iterate over the values in the collection

  • While traversing referenced objects it can filter away those not satisfying one or more constraints, written as predicate expressions between curly brackets like in:

    Student( $grade: /plan/exams{course == "Big Data"}/grades )
  • Items can also be accessed by their index by putting it between square brackets like in:

    Student( $grade: /plan/exams[0]/grades )

    To adhere to Java convention OOPath indexes are 0-based, compared to XPath 1-based

The introduction of PHREAK as default algorithm for the Drools engine made the rules' evaluation lazy. This new Drools lazy behavior allowed a relevant performance boost but, in some very specific cases, breaks the semantic of a few Drools features.

More precisely in some circumstances it is necessary to propagate the insertion of new fact into th session immediately. For instance Drools allows a query to be executed in pull only (or passive) mode by prepending a '?' symbol to its invocation as in the following example:


In this case, since the query is passive, it shouldn't react to the insertion of a String matching the join condition in the query itself. In other words this sequence of commands

KieSession ksession = ...
ksession.insert(1);
ksession.insert("1");
ksession.fireAllRules();

shouldn't cause the rule R to fire because the String satisfying the query condition has been inserted after the Integer and the passive query shouldn't react to this insertion. Conversely the rule should fire if the insertion sequence is inverted because the insertion of the Integer, when the passive query can be satisfied by the presence of an already existing String, will trigger it.

Unfortunately the lazy nature of PHREAK doesn't allow the engine to make any distinction regarding the insertion sequence of the two facts, so the rule will fire in both cases. In circumstances like this it is necessary to evaluate the rule eagerly as done by the old RETEOO-based engine.

In other cases it is required that the propagation is eager, meaning that it is not immedate, but anyway has to happen before the engine/agenda starts scheduled evaluations. For instance this is necessary when a rule has the no-loop or the lock-on-active attribute and in fact when this happens this propagation mode is automatically enforced by the engine.

To cover these use cases, and in all other situations where an immediate or eager rule evaluation is required, it is possible to declaratively specify so by annotating the rule itself with @Propagation(Propagation.Type), where Propagation.Type is an enumeration with 3 possible values:

  • IMMEDIATE means that the propagation is performed immediately.

  • EAGER means that the propagation is performed lazily but eagerly evaluated before scheduled evaluations.

  • LAZY means that the propagation is totally lazy and this is default PHREAK behaviour

This means that the following drl:


will make the rule R to fire if and only if the Integer is inserted after the String, thus behaving in accordance with the semantic of the passive query.

A new KIE Execution Server was created with the goal of supporting the deployment of kjars and the automatic creation of REST endpoints for remote rules execution. This initial implementation supports provisioning and execution of kjars via REST without any glue code.

A user interface was also integrated into the workbench for remote provisioning. See the workbench's New&Noteworthy for details.

Figure 2.30. Kie Server interface

@Path("/server")
public interface KieServer {
    
    @GET
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getInfo();
    
    @POST
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response execute( CommandScript command );
    
    @GET
    @Path("containers")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response listContainers();
    
    @GET
    @Path("containers/{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getContainerInfo( @PathParam("id") String id );
    
    @PUT
    @Path("containers/{id}")
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response createContainer( @PathParam("id") String id, KieContainerResource container );
    
    @DELETE
    @Path("containers/{id}")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response disposeContainer( @PathParam("id") String id );
    
    @POST
    @Path("containers/{id}")
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response execute( @PathParam("id") String id, String cmdPayload );
    
    @GET
    @Path("containers/{id}/release-id")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getReleaseId( @PathParam("id") String id);

    @POST
    @Path("containers/{id}/release-id")
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response updateReleaseId( @PathParam("id") String id, ReleaseId releaseId );
    
    @GET
    @Path("containers/{id}/scanner")
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response getScannerInfo( @PathParam("id") String id );
    
    @POST
    @Path("containers/{id}/scanner")
    @Consumes({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Response updateScanner( @PathParam("id") String id, KieScannerResource resource );
    
} 

It is now possible to define both the delay and interval of an interval timer as an expression instead of a fixed value. To do that it is necessary to declare the timer as an expression one (indicated by "expr:") as in the following example:


The expressions, $d and $p in this case, can use any variable defined in the pattern matching part of the rule and can be any String that can be parsed in a time duration or any numeric value that will be internally converted in a long representing a duration expressed in milliseconds.

Both interval and expression timers can have 3 optional parameters named "start", "end" and "repeat-limit". When one or more of these parameters are used the first part of the timer definition must be followed by a semicolon ';' and the parameters have to be separated by a comma ',' as in the following example:


The value for start and end parameters can be a Date, a String representing a Date or a long, or more in general any Number, that will be transformed in a Java Date applying the following conversion:

new Date( ((Number) n).longValue() )

Conversely the repeat-limit can be only an integer and it defines the maximum number of repetitions allowed by the timer. If both the end and the repeat-limit parameters are set the timer will stop when the first of the two will be matched.

The using of the start parameter implies the definition of a phase for the timer, where the beginning of the phase is given by the start itself plus the eventual delay. In other words in this case the timed rule will then be scheduled at times:

start + delay + n*period

for up to repeat-limit times and no later than the end timestamp (whichever first). For instance the rule having the following interval timer

timer ( int: 30s 1m; start="3-JAN-2010" )

will be scheduled at the 30th second of every minute after the midnight of the 3-JAN-2010. This also means that if for example you turn the system on at midnight of the 3-FEB-2010 it won't be scheduled immediately but will preserve the phase defined by the timer and so it will be scheduled for the first time 30 seconds after the midnight. If for some reason the system is paused (e.g. the session is serialized and then deserialized after a while) the rule will be scheduled only once to recover from missing activations (regardless of how many activations we missed) and subsequently it will be scheduled again in phase with the timer.

The workbench has had a big overhaul using a new base project called UberFire. UberFire is inspired by Eclipse and provides a clean, extensible and flexible framework for the workbench. The end result is not only a richer experience for our end users, but we can now develop more rapidly with a clean component based architecture. If you like he Workbench experience you can use UberFire today to build your own web based dashboard and console efforts.

As well as the move to a UberFire the other biggest change is the move from JCR to Git; there is an utility project to help with migration. Git is the most scalable and powerful source repository bar none. JGit provides a solid OSS implementation for Git. This addresses the continued performance problems with the various JCR implementations, which would slow down once the number of files and number of versions become too high. There has been a big "low tech" drive, to remove complexity. Everything is now stored as a file, including meta data. The database is only there to provide fast indexing and search. So importing and exporting is all standard Git and external sites, like GitHub, can be used to exchange repositories.

In 5.x developers would work with their own source repository and then push JCR, via the team provider. This team provider was not full featured and not available outside Eclipse. Git enables our repository to work any existing Git tool or team provider. While not yet supported in the UI, this will be added over time, it is possible to connect to the repo and tag and branch and restore things.


The Guvnor brand leaked too much from its intended role; such as the authoring metaphors, like Decision Tables, being considered Guvnor components instead of Drools components. This wasn't helped by the monolithic projects structure used in 5.x for Guvnor. In 6.0 Guvnor 's focus has been narrowed to encapsulates the set of UberFire plugins that provide the basis for building a web based IDE. Such as Maven integration for building and deploying, management of Maven repositories and activity notifications via inboxes. Drools and jBPM build workbench distributions using Uberfire as the base and including a set of plugins, such as Guvnor, along with their own plugins for things like decision tables, guided editors, BPMN2 designer, human tasks.

The "Model Structure" diagram outlines the new project anatomy. The Drools workbench is called KIE-Drools-WB. KIE-WB is the uber workbench that combines all the Guvnor, Drools and jBPM plugins. The jBPM-WB is ghosted out, as it doesn't actually exist, being made redundant by KIE-WB.


Important

KIE Drools Workbench and KIE Workbench share a common set of components for generic workbench functionality such as Project navigation, Project definitions, Maven based Projects, Maven Artifact Repository. These common features are described in more detail throughout this documentation.

The two primary distributions consist of:

  • KIE Drools Workbench

    • Drools Editors, for rules and supporting assets.

    • jBPM Designer, for Rule Flow and supporting assets.

  • KIE Workbench

    • Drools Editors, for rules and supporting assets.

    • jBPM Designer, for BPMN2 and supporting assets.

    • jBPM Console, runtime and Human Task support.

    • jBPM Form Builder.

    • BAM.

Workbench highlights:

  • New flexible Workbench environment, with perspectives and panels.

  • New packaging and build system following KIE API.

    • Maven based projects.

    • Maven Artifact Repository replaces Global Area, with full dependency support.

  • New Data Modeller replaces the declarative Fact Model Editor; bringing authoring of Java classes to the authoring environment. Java classes are packaged into the project and can be used within rules, processes etc and externally in your own applications.

  • Virtual File System replaces JCR with a default Git based implementation.

    • Default Git based implementation supports remote operations.

    • External modifications appear within the Workbench.

  • Incremental Build system showing, near real-time validation results of your project and assets.

The editors themselves are largely unchanged; however of note imports have moved from the package definition to individual editors so you need only import types used for an asset and not the package as a whole.