Skip to main content
In this section, we’ll explore the foundational components that make up DRL files. Understanding these building blocks is essential for creating well-structured and maintainable rule systems.

DRL File Structure

A typical DRL file contains the following components, usually in this order:
Let’s explore each of these components in detail.

Packages in DRL

The package declaration is required at the beginning of every DRL file and serves two important purposes:
  1. Organizational structure: Packages group related rules together, similar to Java packages
  2. Namespace definition: Provides a unique namespace for rules, queries, and declared types

Syntax

The package name follows Java package naming conventions, typically using reverse domain notation.

Example

Best Practices

  • Logical grouping: Organize rules into packages based on business domain or functionality
  • Consistency with Java: Align DRL packages with your Java package structure
  • Avoid default package: Always specify a package explicitly for clarity and organization

Package Scope

Rules, queries, and declared types are scoped to their package. This means:
  • Rule names must be unique within a package
  • Imported classes are available to all rules in the package
  • Global variables are accessible throughout the package

Rule Units in DRL

Rule units are a modern approach to organizing related rules and their data sources. A rule unit:
  1. Defines the data sources that rules can act upon
  2. Groups related rules into a cohesive unit
  3. Provides clear boundaries and encapsulation
  4. Enables more targeted rule execution

Declaring a Rule Unit

Unit Implementation in Java

For each rule unit declared in DRL, you’ll need a corresponding Java class:

Data Sources

Rule units work with three types of data sources:
  1. DataStore: A mutable collection that supports adding, removing, and updating facts
  2. DataStream: An append-only stream of facts, similar to a queue
  3. SingletonStore: A container for a single value that can be set or cleared

Using Data Sources in Rules

To reference facts from a data source, use the OOPath syntax with a leading slash:

Benefits of Rule Units

  • Encapsulation: Related rules and data are bundled together
  • Modularity: Units can be developed, tested, and deployed independently
  • Clarity: Clear boundaries for rule scope and data access
  • Performance: Rules only react to relevant data sources
  • REST Integration: Units can be automatically exposed as REST endpoints

Import Statements in DRL

Import statements in DRL work similarly to Java imports, allowing you to use external classes without their fully qualified names.

Syntax

Examples

Types of Imports

  1. Class Imports: Standard Java class imports import java.util.Date;
  2. Package Imports: Import all classes from a package import ai.aletyx.model.*;
  3. Static Imports: Import static methods or fields import static ai.aletyx.Constants.MAX_LOAN_AMOUNT;
  4. Function Imports: Import functions for use in rules import function ai.aletyx.utils.DateUtils.daysBetween;
  5. Accumulate Function Imports: Import custom accumulate functions import accumulate ai.aletyx.functions.WeightedAverage weightedAvg;

Automatic Imports

Drools automatically imports:
  • Classes from the same package as the DRL file
  • Classes from the java.lang package

Best Practices

  • Explicitly import classes for clarity
  • Use fully qualified names for occasional usage to avoid unnecessary imports
  • Group imports logically (Java standard, domain-specific, etc.)
  • Consider package organization to minimize import complexity

Type Declarations

Type declarations allow you to define new fact types directly in DRL files. This is useful when:
  • You don’t want to create Java classes for simple fact types
  • You need to add metadata to existing types
  • You’re prototyping and want to quickly define a data model

Declaring a New Type

Example

Adding Metadata to Types

Extending Types

Using Declared Types

Once declared, you can use these types in your rules:

Common Type Metadata

  • @role(fact|event): Specifies if the type is a regular fact or an event
  • @timestamp: Defines which field contains the event timestamp
  • @duration: Specifies which field defines the event duration
  • @expires: Sets a time after which events automatically expire
  • @key: Marks fields to be used in equals and hashCode methods

Rule Structure

Now let’s examine the structure of individual rules in detail:

Rule Name

Every rule must have a unique name within its rule unit. Names can contain spaces and should be descriptive of the rule’s purpose.

Rule Attributes

Rule attributes modify the behavior of the rule. They are optional and are placed before the when section:
Common attributes include:
  • salience: Sets rule priority (higher executes first)
  • no-loop: Prevents the rule from re-activating due to its own actions
  • date-effective/date-expires: Time window when the rule is active
  • duration: Delay before rule actions execute
  • timer: Schedule-based execution timing
  • lock-on-active: Stronger version of no-loop

Conditions (when)

The when section defines the conditions under which the rule should fire. It consists of one or more patterns that match against facts in working memory:
Patterns can include:
  • Data source matching (/orders)
  • Constraints (total > 1000)
  • Bindings to variables ($order: /orders)
  • Property access (customer.status)
  • Conditional elements (and, or, not, exists, etc.)

Actions (then)

The then section defines the actions to take when the conditions are met. This is Java code that executes when the rule is triggered. Unlike the when section, which uses its own pattern matching syntax, the then section contains plain Java code:
Common actions include:
  • Modifying matched facts
  • Creating new facts
  • Adding/removing facts from data sources
  • Logging or sending notifications
  • Calling external services

Summary

In this section, we’ve covered the fundamental building blocks of DRL:
  • Packages: Namespaces that organize related rules
  • Rule Units: Containers for related rules and data sources
  • Imports: References to external classes and functions
  • Type Declarations: Definitions for fact types
  • Rule Structure: The components of individual rules
Understanding these building blocks provides the foundation for creating well-structured and maintainable rule systems. In the next sections, we’ll dive deeper into rule conditions and actions, exploring the rich expression capabilities of DRL.