Business Rules Manager

From wiki.searchtechnologies.com
Jump to: navigation, search

For Information on Aspire 3.1 Click Here

Business Rules Manager
Factory  aspire-business-rules
subType  manager
Inputs  Servlet commands
Outputs  Business rules to a database
Enterprise Add-On Feature

The business rule manager is used in conjunction with the Business Rules Engine to allow processing of business rules. Business rule processing allows a document flowing through Aspire to be manipulated based on a set of discrete rules. This manipulation may include addition of information to the document or modification of the information in a document. Also in some cases, a rule can indicate that a document should not be processed any more and should be removed (job terminated) from Aspire. Business rules can be used in any situation where document manipulation is required and is equally applicable for indexing, querying or security related pipelines.

Business rules are stored in a database and the business rule manager is designed as a support component allowing creation, updating and deletion of these rules. It is driven using servlet commands. The manager also provides a plugin for the Aspire administration interface, allowing the rule administration to be performed via the same user interface as all other configuration.

Business Rules

There are a number of different rule types - set, choice and simple. Sets are groups of rules that can be used to build up hierarchical processing. Choice rules allow conditional processing of other rules (or sets) and simple rules perform some action on the document. Rules also have flags to indicate that no further rules should be processed (allowing a quick 'termination' of rule processing) and a flag to indicate if this rule in enabled. This allows rules to be created and then disabled, but not deleted (either for testing or short term changes to processing).

Simple and choice rules are implemented using Groovy scripts. Simple rules contain Groovy scripts that typically alter the AspireObject associated with the job (for example, they may set a field to a specific value). However, they could also terminate the job or access other components. Choice rules contain Groovy which typically evaluates a condition in the AspireObject associated with the job (for example, they may check a field for a specific value) and executes children in the hierarchy if the condition is met.

Rules are formed into execution plans, allowing rules to be re-used and different sets of rules to be applied to different business activities (say, document indexing and searching). Within an execution plan, rules are executed in an order given by a sequence.

Rule sets

Rule sets allow rules to be grouped (perhaps into functional areas). The sets themselves do not have any Groovy script associated with them and therefore do not directly alter the document. Rule sets may have simple rules, choices or further rule sets as children. Rule sets may be disabled, meaning no child rules are executed.

Simple rules

Simple rules have a Groovy script associated with them, typically to change a value within a document. Simple rules may be disabled, meaning that they are skipped. Simple rules may also have a terminate flag set, causing no further rules to be executed after this one. A simple rule could also terminate the Aspire job using Groovy:

 job.setTerminate();

Simple rules cannot have children.

Choice Rules & Conditions

Choice rules have a Groovy script associated with them that is used to evaluate whether a certain condition is met. Choice rules need child conditions in order to function. The Groovy script is executed and the return from that script is compared with the value returned from the execution of the child conditions. If there is a match, the child rules of the condition are executed. Choice rules may only have conditions as children.

Condition

The condition is a Groovy script which is evaluated and compared against the return from a choice rule. If the values match, the condition's children are executed. Conditions may have sets, simple rules or further choice rules as children.

Default Condition

Conditions that have no Groovy script are considered to be the default condition and executed if no other condition is matched.

Types of Choice Rules

Currently, two different types of choice rule are supported.

BOOLEAN choice rule

This rule evaluates a Groovy script of the following form and expects child conditions of true and/or false.

 doc.field == "value"
SWITCH choice rule

This rule evaluates a Groovy script of the following form and expects child conditions of the possible values of this variable (say, "valueOne", "valueTwo", etc.).

 doc.field

Terminating Rule Processing

Selecting this option prevents further rules from being evaluated should this rule be run. Normally rules are executed in sequence order until there are no more rules, but this option prevents this. This option is automatically selected if the Aspire job is terminated by the Groovy script.

Special condition & action variables

  • The doc variable allows access to the job's AspireObject document.
  • The job variable allows access to the job.
  • The component variable allows access the engine or manager component's features (such as logging).
  • Access to other components may be obtained using component.getComponent(name).
  •  (1.1 Release)   The globals variable may be used to share global information between rules.
    • For example, globals.myVar = "myValue" to set a value in one rule, println globals.myVar in another.
    • NOTE: the globals variable has an underlying hash map (ConcurrentHashMap<String, Object>) and can store any object. Different rules engines will use different hash maps, so this variable is only intended to share non job/document information between rules in the same engine. For example, you could create a rule that loads a dictionary into globals.dict if it is not already set. Subsequent rules can then access this dictionary, knowing it's already been loaded.

See the Groovy Scripting page for further details.

Execution Plans

Rules must be allocated to execution plans in order that they may be used. A plan is a logical grouping of business rules, probably by functional area (say, indexing or searching). Business Rules Engines process only a single plan, meaning that multiple plans can be administered by the business rule manager and then multiple Business Rules Engines can be configured - each handling a different plan.

Rule Templates

When creating rules, templates may be used to ease configuration. These templates can contain the rule type, Groovy script and a DXF template to render in the interface. User-defined templates are held in a file with internal templates added by the manager.

Internal templates

Internal templates define the choice rule types BOOLEAN and SWITCH and the rule set.

The definition is shown below:

  <templates>
    <template name="BOOLEAN" type="choice" internal="true">
      <ruleDescription>Tests if the value of '${field}' is '${value}'</ruleDescription>
      <dxf>
        <![CDATA[
          <dxf:template version="1.0" xmlns:dxf="http://www.searchtechnologies.com/DXF/2011">
            <properties>
              <field display="Field name" type="string">
                <dxf:help>The field from the document to test</dxf:help>
              </field>
              <value display="Value" type="string">
                <dxf:help>The value to test for</dxf:help>
              </value>
            </properties>
          </dxf:template>
        ]]>
      </dxf>
      <description>Built-in boolean test</description>
      <action><![CDATA[doc.${field}?.text() == "${value}"]]></action>
    </template>
    <template name="SWITCH" type="choice" internal="true">
      <ruleDescription>Switches based on the value of '${field}'</ruleDescription>
      <dxf>
        <![CDATA[
          <dxf:template version="1.0" xmlns:dxf="http://www.searchtechnologies.com/DXF/2011">
            <properties>
              <field display="Field name" type="string">
                <dxf:help>The field from the document to test. The "case" values are specified in the child rules</dxf:help>
              </field>
            </properties>
          </dxf:template>
        ]]>
      </dxf>
      <description>Built-in switch</description>
      <action><![CDATA[doc.${field}?.text()]]></action>
    </template>
    <template name="RULE SET" type="set" internal="true">
      <description>Rule set</description>
    </template>
  </templates>

NOTE: internal templates are not exported to export files.

External templates

External templates are read from an XML file. An example is given below:

  <templates>
    <template name="JobTerminate" type="simple">
      <description>Terminates the job</description>
      <action><![CDATA[job.terminate()]]></action>
    </template>
    <template name="SetStringValue" type="simple">
      <ruleDescription>Assigns the value "${value}" to the field ${field}</ruleDescription>
      <dxf>
        <![CDATA[
          <dxf:template version="1.0" xmlns:dxf="http://www.searchtechnologies.com/DXF/2011">
            <properties>
              <field display="Field name" type="string">
                <dxf:help>The field from the document to modify</dxf:help>
              </field>
              <value display="Value" type="string">
                <dxf:help>The string value to set</dxf:help>
              </value>
            </properties>
          </dxf:template>
        ]]>
      </dxf>
      <description>Assigns a string value to a field</description>
      <action><![CDATA[doc.${field} = "${value}"]]></action>
    </template>
  </templates>

Configuration

Element Type Default Description
rdb String None The path to the RDB component to use.
allowCustomRule boolean false Allows the creation of custom rules. If this parameter is false, any rule created will have to be based on a template and will only be able to parameterize the condition and action from the template.
disableInternalTemplates boolean false True if the internally defined templates should be disabled (if for instance you wish to override them).
templates String If set, load extra templates from the given file; see here for an example of the template file. Internal templates are added after the file has been loaded (unless disabled) and therefore potentially mask your templates if conflicting names are used. When importing rules to the database, the template definitions are read from the import file.
import String If set, take a file of business rules (previously exported from a Business Rules Manager) and import them into an empty database. If the database already contains rules, the no import will take place. When importing rules to the database, the template definitions are read from this file.


Example Configuration

Database only

 <component name="myBRM" subType="manager" factoryName="aspire-business-rules">
   <debug>true</debug>
   <rdb>/BusinessRulesManager/BRRDB</rdb>
   <templates>data/templates.xml</templates>
 </component>

Import rules from an export file

 <component name="myBRM" subType="manager" factoryName="aspire-business-rules">
   <debug>true</debug>
   <rdb>/BusinessRulesManager/BRRDB</rdb>
   <import>data/export.xml</import>
   <!-- Rules DB must be empty for import to happen -->
   <!-- Templates now come from <import> file, regardless -->
 </component>

Database

The business rule manager (and engine) require a connection to a database holding the business rules. The schema consists of two tables, rule and plan_node.

rule

This table holds the information the rule. It holds the name, description and type (simple, choice, set) of the rule as well as the rule allows further rule processing. In the case of simple and choice rules, the table also holds the Groovy script and if the rule was generated from a template, the name of the template and the properties entered when the template was used.

plan_node

This table hold the rule hierarchy and order of execution of the rules, maintaining the parent/child relationships. For conditions, this table holds the Groovy script which is evaluated to give the condition value.

Database schema

The script below is suitable for a Derby database:

  CREATE TABLE rule(
      name varchar(64) NOT NULL,
      description varchar(256),
      type varchar(16) NOT NULL,
      template varchar(64),
      properties varchar(4096),
      terminate smallint NOT NULL,
      action varchar(4096),
      CONSTRAINT PK_rule PRIMARY KEY (name)
  );

  CREATE TABLE plan_node(
      id bigint NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1, INCREMENT BY 1),
      parent_ref bigint,
      plan varchar(64) NOT NULL,
      enabled smallint NOT NULL,
      rule varchar(64),
      "order" smallint,
      condition varchar(1024),
      CONSTRAINT PK_ASPIRE_SCHEDULED_JOBS PRIMARY KEY (id)
  );

  -- FOREIGN KEYS
  ALTER TABLE plan_node ADD CONSTRAINT FK_plan_node_id__plan_node_parent_ref FOREIGN KEY(parent_ref)
      REFERENCES plan_node(id) ON DELETE CASCADE;

  ALTER TABLE plan_node ADD CONSTRAINT FK_plan_node_rule__rule_name FOREIGN KEY(rule)
      REFERENCES rule(name);

  -- INDEXES
  CREATE INDEX IX_rule_type ON rule(
      type ASC
  );
  CREATE INDEX IX_plan_node_parent_ref ON plan_node(
      parent_ref ASC
  );
  CREATE INDEX IX_plan_node_enabled ON plan_node(
      enabled ASC
  );
  CREATE INDEX IX_plan_node_plan ON plan_node(
      plan ASC
  );
  CREATE INDEX IX_plan_node_order ON plan_node(
      "order" ASC
  );

Database Diagram

Business rules schema.jpg

Servlet Commands

The Business Rules Manager supports the following servlet commands (via http://server:port/myBRM?cmd=XXXX&param=value):

template

Performs template related functions based on the input parameters.

The following parameters are supported:

Parameter Type Default Description
action String The action to perform. Allowable values are:

get: gets one or all templates

all boolean false If true, all templates are returned. If false, the name parameter is expected.
name String Return the template with the given name.
sparse boolean false If false, all the template information is returned, otherwise only the name and description are.
dxfForm String If specified, the template's DXF is evaluated and returned in the response using the given form name.

rule

Performs rule related functions based on the input parameters.

The following parameters are supported:

Parameter Type Default Description
action String The action to perform. Allowable values are:

get: gets one or all rules; create: creates a new rule; update: updates an existing rule; delete: deletes an existing rule.
NOTE: creates and updates require all information for the rule to be sent in a single command. If you are updating a rule and wish a previously set value to remain unchanged, you must send that value in the appropriate parameter.
NOTE: creates and updates will return the information in the updated rule as if a get for the new rule had been performed.

all boolean false If true, all rules are returned. If false, the name parameter is expected.
name String Perform the requested action for the rule with the given name.
sparse boolean false Used when getting rules (action=get). If false, all the template information is returned, otherwise only the name and description are.
type String The type of the rule to create/update/delete. Can be one of simple, choice or set.
description String The description for the rule.
template String The name of the template if this rule is associated with one.
properties String The properties associated with the rule (if the rule is associated with a template).
terminate boolean false If true, no further rules should be processed after this one.
dxfForm String If specified, and the rule has a template, it's DXF is evaluated and returned in the response using the given form name.

plan

Performs plan (hierarchy) related functions based on the input parameters.

The following parameters are supported:

Parameter Type Default Description
action String The action to perform. Allowable values are:

get: gets the named plan; create: creates a new reference to an existing rule in the plan or creates a new condition, depending on the type parameter; update: updates an existing reference in the plan or updates a condition, depending on the type parameter; move: moves an existing reference in the plan or a condition, depending on the type parameter; delete: deletes a reference to a rule or condition in the plan, depending on the type parameter.
NOTE: all information must be sent in a single command. If you are updating and wish a previously set value to remain unchanged, you must send that value in the appropriate parameter.
NOTE: creates, updates, moves and deletes will return the entire plan as if a get had been performed.

plan String index The name of the plan which is being changed.
sparse boolean false Used when getting rules (action=get). If false, all the template information is returned, otherwise only the name and description are.
type String The type of node being actioned - can be reference (to a rule) or condition.
parent long the root node For creates, the id of the parent node in the hierarchy

For moves, the id of the new parent node in the hierarchy.

order long the root node For creates, the order (sequence) of execution of the node within the parent node.

For moves, the new order (sequence) of execution of the node within the parent node.

rule String The name of the rule being referenced (not appropriate for conditions).
enabled boolean true Whether the reference or condition is enabled.
value String The value for conditions (not appropriate for references).

export

Exports the templates, rules and hierarchy to a file. This file may later be used as an import file to the Business Rules Manager or a plan file for the Business Rules Engine.

NOTE: Internal templates are not included in the export file.

Parameter Type Default Description
fileName String The name of the file to export to.

Example export file

<?xml version="1.0" encoding="UTF-8"?>
<businessRules>
  <plans>
    <plan name="testPlan">
      <ruleRef name="setFieldOne" order="1"/>
      <ruleRef name="ruleStopBool" order="2">
        <conditions>
          <condition enabled="true">
            <plan>
              <ruleRef name="stopProcessing" order="1"/>
            </plan>
            <value>true</value>
          </condition>
        </conditions>
      </ruleRef>
      <ruleRef name="switch1" order="3">
        <conditions>
          <condition enabled="true">
            <plan>
              <ruleRef name="switch1WasAFolder" order="1">
                <plan>
                  <ruleRef name="switch1WasA" order="1"/>
                  <ruleRef name="bool1" order="2">
                    <conditions>
                      <condition enabled="true">
                        <plan>
                          <ruleRef name="bool1WasTrue" order="1"/>
                        </plan>
                        <value>true</value>
                      </condition>
                      <condition enabled="true">
                        <plan>
                          <ruleRef name="bool1WasFalse" order="2"/>
                        </plan>
                        <value>false</value>
                      </condition>
                    </conditions>
                  </ruleRef>
                </plan>
              </ruleRef>
            </plan>
            <value>"A"</value>
          </condition>
          <condition enabled="true">
            <plan>
              <ruleRef name="switch1WasBFolder" order="1">
                <plan>
                  <ruleRef name="switch1WasB" order="1"/>
                  <ruleRef name="switch2" order="2">
                    <conditions>
                      <condition enabled="true">
                        <plan>
                          <ruleRef name="switch2WasY" order="1"/>
                        </plan>
                        <value>"Y"</value>
                      </condition>
                      <condition enabled="true">
                        <plan>
                          <ruleRef name="switch2WasZ" order="1"/>
                        </plan>
                        <value>"Z"</value>
                      </condition>
                      <condition default="true" enabled="true">
                        <plan>
                          <ruleRef name="switch2WasDefaultFolder" order="1">
                            <plan>
                              <ruleRef name="switch2WasDefault" order="1"/>
                              <ruleRef name="jobTerminate" order="2"/>
                            </plan>
                          </ruleRef>
                        </plan>
                      </condition>
                    </conditions>
                  </ruleRef>
                </plan>
              </ruleRef>
            </plan>
            <value>"B"</value>
          </condition>
        </conditions>
      </ruleRef>
      <ruleRef name="setFieldTwo" order="4"/>
      <ruleRef name="setFieldThree" enabled="false" order="5"/>
    </plan>
  </plans>
  <templates>
    <template name="JobTerminate" type="simple">
      <description>Terminates the job</description>
      <action><![CDATA[
	    component.warn("Job '%s' terminated by rule '%s'", job.getJobId(), rule.getName())
	    job.terminate()
      ]]></action>
    </template>
    <template name="SetStringValue" type="simple">
      <ruleDescription>Assigns the value "${value}" to the field ${field}</ruleDescription>
      <dxf><![CDATA[
		
		  <dxf:template version="1.0" xmlns:dxf="http://www.searchtechnologies.com/DXF/2011">
		    <properties>
              <field display="Field name" type="string">
                <dxf:help>The field from the document to modify</dxf:help>
              </field>
              <value display="Value" type="string">
                <dxf:help>The string value to set</dxf:help>
              </value>
            </properties>
          </dxf:template>
        ]]></dxf>
      <description>Assigns a string value to a field</description>
      <action><![CDATA[doc.${field} = "${value}"]]></action>
    </template>
  </templates>
  <rules>
    <rule name="bool1" template="BOOLEAN" type="choice" terminate="false">
      <description>Test on bool1</description>
      <properties>
        <property name="field">bool1</property>
        <property name="value">value</property>
      </properties>
    </rule>
    <rule name="bool1WasFalse" type="simple" terminate="false">
      <description>Sets bool1Result to false</description>
      <action><![CDATA[doc.bool1Result = "false"]]></action>
    </rule>
    <rule name="bool1WasTrue" type="simple" terminate="false">
      <description>Sets bool1Result to true</description>
      <action><![CDATA[doc.bool1Result = "true"]]></action>
    </rule>
    <rule name="jobTerminate" template="JobTerminate" type="simple" terminate="false">
      <description>Terminates the job</description>
    </rule>
    <rule name="ruleStopBool" template="BOOLEAN" type="choice" terminate="false">
      <description>Test to stop processing</description>
      <properties>
        <property name="field">stopProcessing</property>
        <property name="value">yes</property>
      </properties>
    </rule>
    <rule name="setFieldOne" template="SetStringValue" type="simple" terminate="false">
      <description>Sets fieldOne to valueOne</description>
      <properties>
        <property name="field">fieldOne</property>
        <property name="value">valueOne</property>
      </properties>
    </rule>
    <rule name="setFieldThree" type="simple" terminate="false">
      <description>Sets fieldThree to valueThree</description>
      <action><![CDATA[doc.fieldThree = "valueThree"]]></action>
    </rule>
    <rule name="setFieldTwo" template="SetStringValue" type="simple" terminate="false">
      <description>Sets fieldTwo to valueTwo</description>
      <properties>
        <property name="field">fieldTwo</property>
        <property name="value">valueTwo</property>
      </properties>
    </rule>
    <rule name="stopProcessing" type="simple" terminate="true">
      <description>Stops rule processing</description>
      <action><![CDATA[doc.stopped = "yes"]]></action>
    </rule>
    <rule name="switch1" template="SWITCH" type="choice" terminate="false">
      <description>Switch on switch1</description>
      <properties>
        <property name="field">switch1</property>
      </properties>
    </rule>
    <rule name="switch1WasAFolder" type="set" terminate="false">
      <description>Set of rules to run when switch1WasA</description>
    </rule>
    <rule name="switch1WasA" type="simple" terminate="false">
      <description>Sets switch1Result to A</description>
      <action><![CDATA[doc.switch1Result = "A"]]></action>
    </rule>
    <rule name="switch1WasB" type="simple" terminate="false">
      <description>Sets switch1Result to B</description>
      <action><![CDATA[doc.switch1Result = "B"]]></action>
    </rule>
    <rule name="switch1WasBFolder" type="set" terminate="false">
      <description>Set of rules to run when switch1WasB</description>
    </rule>
    <rule name="switch2" template="SWITCH" type="choice" terminate="false">
      <description>Switch on switch2</description>
      <properties>
        <property name="field">switch2</property>
      </properties>
    </rule>
    <rule name="switch2WasDefaultFolder" type="set" terminate="false">
      <description>Set of rules to run when switch2WasDefault</description>
    </rule>
    <rule name="switch2WasDefault" type="simple" terminate="false">
      <description>Sets switch2Result to default</description>
      <action><![CDATA[doc.switch2Result = "default"]]></action>
    </rule>
    <rule name="switch2WasY" type="simple" terminate="false">
      <description>Sets switch2Result to Y</description>
      <action><![CDATA[doc.switch2Result = "Y"]]></action>
    </rule>
    <rule name="switch2WasZ" type="simple" terminate="false">
      <description>Sets switch2Result to Z</description>
      <action><![CDATA[
	  	doc.switch2Result = "Z"
		component.warn("SWITCH 2 WAS Z!!");
	  ]]></action>
    </rule>
  </rules>
</businessRules>

dump

The dump command takes no parameters. It produces SQL insert statements that can be used to re-construct the rules database at a later date. It allows rules to be created locally before being included in an app bundle for distribution to a customer. It produces SQL of the following form:

-- ****************************************************************
-- * Aspire business rules
-- ****************************************************************
      
-- Table: rule
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('setFieldOne','Sets fieldOne to valueOne','simple','SetStringValue','<properties><property name="field">fieldOne</property><property name="value">valueOne</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch1','Switch on switch1','choice','SWITCH','<properties><property name="field">switch1</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch1WasAFolder','Set of rules to run where switch1WasA','set',null,null,0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch1WasA','Sets switch1Result to A','simple',null,null,0,'doc.switch1Result = "A"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch1WasBFolder','Set of rules to run where switch1WasB','set',null,null,0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch1WasB','Sets switch1Result to B','simple',null,null,0,'doc.switch1Result = "B"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch2','Switch on switch2','choice','SWITCH','<properties><property name="field">switch2</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch2WasY','Sets switch2Result to Y','simple',null,null,0,'doc.switch2Result = "Y"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch2WasZ','Sets switch2Result to Z','simple',null,null,0,'doc.switch2Result = "Z"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch2WasDefaultFolder','Set of rules to run where switch2WasDefault','set',null,null,0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('switch2WasDefault','Sets switch2Result to default','simple',null,null,0,'doc.switch2Result = "default"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('bool1','Test on bool1','choice','BOOLEAN','<properties><property name="field">bool1</property><property name="value">value</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('bool1WasTrue','Sets bool1Result to true','simple',null,null,0,'doc.bool1Result = "true"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('bool1WasFalse','Sets bool1Result to false','simple',null,null,0,'doc.bool1Result = "false"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('setFieldTwo','Sets fieldTwo to valueTwo','simple','SetStringValue','<properties><property name="field">fieldTwo</property><property name="value">valueTwo</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('setFieldThree','Sets fieldThree to valueThree','simple',null,null,0,'doc.fieldThree = "valueThree"');
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('jobTerminate','Terminates the job','simple','JobTerminate',null,0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('ruleStopBool','Test to stop processing','choice','BOOLEAN','<properties><property name="field">stopProcessing</property><property name="value">yes</property></properties>',0,null);
insert into rule(NAME,DESCRIPTION,TYPE,TEMPLATE,PROPERTIES,TERMINATE,ACTION) values('stopProcessing','Stops rule processing','simple',null,null,1,'doc.stopped = "yes"');


-- Table: plan_node
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(1,null,'index',1,'setFieldOne',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(2,null,'index',1,'ruleStopBool',2,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(3,null,'index',1,'switch1',3,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(4,null,'index',1,'setFieldTwo',4,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(5,null,'index',0,'setFieldThree',5,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(6,2,'index',1,null,null,'true');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(7,6,'index',1,'stopProcessing',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(8,3,'index',1,null,null,'"A"');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(9,3,'index',1,null,null,'"B"');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(10,8,'index',1,'switch1WasAFolder',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(11,9,'index',1,'switch1WasBFolder',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(12,10,'index',1,'switch1WasA',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(13,11,'index',1,'switch1WasB',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(14,10,'index',1,'bool1',2,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(15,14,'index',1,null,null,'true');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(16,14,'index',1,null,null,'false');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(17,15,'index',1,'bool1WasTrue',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(18,16,'index',1,'bool1WasFalse',2,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(19,11,'index',1,'switch2',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(20,19,'index',1,null,null,'"Y"');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(21,19,'index',1,null,null,'"Z"');
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(22,19,'index',1,null,null,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(23,20,'index',1,'switch2WasY',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(24,21,'index',1,'switch2WasZ',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(25,22,'index',1,'switch2WasDefaultFolder',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(26,25,'index',1,'switch2WasDefault',1,null);
insert into plan_node(ID,PARENT_REF,PLAN,ENABLED,RULE,order,CONDITION) values(27,25,'index',1,'jobTerminate',2,null);
...