WebSphere ILog JRules 域的介绍和定制

引言

随着企业业务的不断发展,越来越多的企业正经历着以下的情形:

  • 企业需要对于业务系统的频繁变化做出及时的关注和响应,例如,竞争对手或经济环境的变化等。
  • 企业需要实现决策的自动化,从而支持组织的业务模式和产品服务。

业务规则管理系统在定制和组合业务应用程序中可以实现策略自动化,是解决以上问题的一个好的解决方案。业务规则管理系统支持对组织策略以及与这些策略相关联的运营决策进行定义、部署、监控和维护,而与核心应用程序代码分割开来。通过使业务规则具体化并提供相应管理工具,业务规则管理系统使业务专家能够定义并维护引导系统行为的决策,减少更新生产系统所需的时间和精力,同时增强组织对业务环境中的变革作出响应的能力。业务规则管理系统既可以降低应用程序维护成本,促使应用程序间的业务策略实施更为精确并且一致,还可以改善业务和 IT 部门之间的协作。

IBM WebSphere ILOG JRules 是业界先进的业务规则管理系统,它为不同的用户角色(开发人员、分析人员、业务人员等)提供了功能强大的编辑工具来管理、追踪、更改规则。WebSphere ILOG JRules 的编辑工具主要包括两部分:

  • WebSphere ILOG Rule Studio:用于定义、修改、部署规则的基于 Eclipse 的开发环境。它允许合作编辑和调试 Java 代码和规则。
  • WebSphere ILOG Rule Team Server:用于定义、修改、部署规则的基于 Web 的开发环境,分布式业务团队可以通过它协作、创建、管理、验证和部署业务规则。

域是 WebSphere ILog JRules 中的业务模型对象中的重要概念,用户可以通过在 WebSphere ILog JRules 编辑工具中配置静态或动态域,更加快速和高效的的编辑、检查和分析业务规则。在下面的章节中,我们将会介绍 WebSphere ILog JRules 中域的概念,以及如何在 WebSphere ILog JRules 编辑工具中配置静态域和动态域。

WebSphere ILog JRules 域的概念简介

业务模型对象 (BOM) 通过提供自然语言词汇表的工具,为用户提供友好的业务规则编辑功能。策略管理人员可以用业务规则语言描述业务逻辑。BOM 包含规则类和方法。作为对象模型,业务模型对象类似于 Java 对象模型。它包括包含在包中的类。每个类都有一组属性、方法和可能嵌套的其他类。BOM 到 XOM 的映射定义了业务模型对象和在运行时使用的执行对象模型(XOM)之间的对应关系。

域对业务模型对象中的类型元素设置了限制。用户可以为类、属性类型、方法的返回类型和参数设置域。主要的域的类型包括:

  • 静态域:字面值、静态引用、有界、集合已近其他域类型
  • 动态域:其中的值由 Java 代码执行设置(通过实现 IlrBOMDomainValueProvider)
  • 枚举域:字面值、静态引用和动态域类型
  • 复杂域:有界、集合和其他域类型

用户可以使用域来实现以下功能:

  • 编辑业务规则:在编辑器中完成代码所需要使用的枚举域来提供有效的设置
  • 检查业务规则:可使用域来报告错误或警告,这些错误和警告有助于验证用户指定的值是否有效
  • 分析业务规则:业务模型对象中的所有域类型都可以用来检查业务规则语法的一致性

案例简介

本文根据一个电信领域的案例来描述如何进行 WebSphere ILog JRules 域的定制。为了占有更多的市场份额,保证企业利润的增长,电信运营商会定期向客户进行产品营销。例如,通过短信渠道向客户发送新产品的推介,或者通过邮件渠道向客户发送一些产品的更新及优惠信息。由于电信运营商的运营渠道众多,并且发起营销活动的目标种类也很多,因此如何准确而高效的基于不同的营销目标、通过不同的营销渠道向客户发送营销信息是电信运营商需要考虑的问题。这里我们通过使用 WebSphere ILog JRules 来编辑营销消息规则来解决以上的问题。规则定义如下图所示。电信运营商将通过不同的营销渠道,根据不同的营销目标类型,向客户发送不同的营销信息。

图 1. 营销信息
WebSphere ILog JRules 域的介绍和定制-LMLPHP

下图描述了电信运营商用于进行产品营销的模型。CampaignActivity 用于描述电信运营商为推介新产品或打击竞争对手而对客户开展的营销活动,CampaignChannel 用于描述进行产品营销的渠道。在这个例子中,我们定义营销渠道(CampaignChannel 类)包括两种: SMS 和 Email,营销目标类型 (CampaignActivity 类的 campaignType 属性 ) 包括两种 :New product broadcast 和 Against Competitor,最终的营销消息将存入营销消息(CampaignActivity 类的 message 属性)结构中。

图 2. 营销信息模型

在 WebSphere ILog JRules Studio 中配置静态域

创建模型

首先我们根据案例需求快速构建一个规则工程,并定义相应的规则,其中不包括域的定义。

  1. 创建一个规则工程 SampleRules, 在工程里创建一个 xsd 文件夹用于保存 xsd 文件,在 xsd 文件夹下新建一个 xsd 文件 Sample.xsd 用于定义模型结构。
  2. 在 Rule Project Map 下点击 Import XOM, 在 Import XOM 对话框中选择 Dynamic Execution Object Model(XSD), 将 Sample.xsd 添加至 Dynamic Bindings 属性框。点击 Rule Project Map 下的 Create BOM, 选择 Sample.xsd 作为 XOM Element。操作完成后,用户可以在 Rule Explorer 当中查看规则的业务模型对象结构。 
    图 3. BOM 结构 WebSphere ILog JRules 域的介绍和定制-LMLPHP
  3. 在 Ruleset Parameters 中创建 activity 作为规则工程的输入和输出。
  4. 根据需求和规则业务模型对象结构,创建一个决策表用于描述营销信息规则,内容格式如下所示:

表 1. 营销信息规则结构

对象名称内容
条件Campaign Channelthe name of the campaign channel of activity is <a string>
Campaign Typethe campaign type of activity is <a string>
结果Campaign Messageset the message of activity to <a string>

通过这种方式定义的规则,用户需要手动输入内容,例如,用户需要手动输入 SMS 和 Emai 作为营销渠道。这种方式需要用户输入大量的内容,很容易出错。如果在规则执行后发现规则引擎没有按指定的规则内容执行,用户很难通过查看规则内容查找原因。接下来我们将会为类和属性类型添加域来解决以上的问题。

为类配置静态域

在这一节中,我们将会为类添加静态域,这里我们选择 CampaignChannel 作为类的例子。

  1. 在规则工程的业务模型对象结构中选择 Campaign Channel。
  2. 在 Members 属性中点击 New 创建新成员。输入名称,选择 org.example.sample.CampaignChannel 作为类型。 
    图 4. 新建成员 WebSphere ILog JRules 域的介绍和定制-LMLPHP
  3. 编辑新成员的属性,设置成员属性为 Static 和 Final 类型,在 Member Verbalization 中添加名称作为域显示的名称。在 BOM to XOM Mapping 中添加定义。General Information 中的 Name 属性是用于标识成员的唯一标识,不能与其他 Name 重复。Member Verbalization 中的 Label 属性是成员显示在规则编辑界面上的名称。BOM to XOM Mapping 定义了业务模型对象和在运行时使用的执行对象模型(XOM)之间的对应关系。 
    图 5. General Information WebSphere ILog JRules 域的介绍和定制-LMLPHP 

    图 6. Member Verbalization WebSphere ILog JRules 域的介绍和定制-LMLPHP

    图 7. BOM to XOM Mapping WebSphere ILog JRules 域的介绍和定制-LMLPHP

  4. 重复以上步骤,添加另一成员。新建的两个 CampaignChannel 成员属性如表所示。

表 2. CampaignChannel 成员 1 属性

TitleContent
NameCampaignChannel1
Typeorg.example.sample.CampaignChannel
StaticYes
FinalYes
LabelSMS
BOM to XOM Mappingorg.example.sample.CampaignChannel temp  =neworg.example.sample.CampaignChannel(); temp.channelId ="CampaignChannel1"; temp.name ="SMS"; temp.description ="SMS"; returntemp;

表 3. CampaignChannel 成员 2 属性

TitleContent
NameCampaignChannel2
Typeorg.example.sample.CampaignChannel
StaticYes
FinalYes
LabelEmail
BOM to XOM Mappingorg.example.sample.CampaignChannel temp  =neworg.example.sample.CampaignChannel(); temp.channelId ="CampaignChannel1"; temp.name ="Email"; temp.description ="Email"; returntemp;
  1. 在 CampaignChannel Class 的 Domain 属性中点击 Create 链接,选择 CampaignChannel1 和 CampaignChannel2 作为与成员。
  2. 更新消息规则的定义,将 Campaign Channel 的定义由“the name of the campaign channel of activity is <a string>”改为“the campaign channel of activity is <an object>”,这时用户就可以利用在域中定义的内容编辑规则,定义在域中的内容将会在用户点击编辑窗口的时候自动列出。 
    图 8. 营销信息规则 WebSphere ILog JRules 域的介绍和定制-LMLPHP

为属性类型配置静态域

在这一节中我们将为类型属性添加域,这里我们选择 CampaignActivity 中的 campaginType 属性作为配置属性类型的例子。

  1. 在规则工程的 BOM 结构中新建一个名为 CampaignType 的类。
  2. 设置 CampginType 的属性。设置 campaign type 作为 Class Verbalization,设置 java.lang.String 作为 BOM to XOM Mapping 的 Execution name 属性。 
    图 9. Class Verbalization WebSphere ILog JRules 域的介绍和定制-LMLPHP 

    图 10. BOM to XOM Mapping WebSphere ILog JRules 域的介绍和定制-LMLPHP

  3. 为 CampaignType 创建新成员。点击 Members 属性下的 New 按钮,输入成员名称,输入 org.example.sample.CampaignType 作为类型。 
    图 11. 创建新成员 WebSphere ILog JRules 域的介绍和定制-LMLPHP
  4. 编辑成员属性。在 General Information 中设置成员具有 Static 和 Final 属性,在 Member Verbalization 中设置 Label 属性,在 BOM to XOM Mapping 中设置对象返回结果。 
    图 12. General Information WebSphere ILog JRules 域的介绍和定制-LMLPHP 

    图 13. Member Verbalization WebSphere ILog JRules 域的介绍和定制-LMLPHP

    图 14. Member Verbalization WebSphere ILog JRules 域的介绍和定制-LMLPHP

  5. 参照以上步骤为 CampaignType 添加属性,属性内容如表格所示。

表 4. CampaignType 成员 1 属性

TitleContent
NameCampaignType1
Typeorg.example.sample.CampaignType
StaticYes
FinalYes
LabelNew product broadcast
BOM to XOM Mappingreturn "New product broadcast";

表 5. CampaignType 成员 2 属性

TitleContent
NameCampaignType2
Typeorg.example.sample.CampaignType
StaticYes
FinalYes
LabelAgainst Competitor
BOM to XOM Mappingreturn "Against Competitor";
    1. 将 CampaignType 的两个成员(CampaignType1 和 CampaignType2)添加至 CampaignType 的域中。
    2. CampaignChannel 中的 campaignType 属性,将 campaignType 的类型由 java.lang.String 改成 org.example.sample.CampaignType。 
      图 15. General Information WebSphere ILog JRules 域的介绍和定制-LMLPHP
    3. 编辑消息规则中的 Campaign Type 条件的定义,将定义由“the campaign type of activity is <a string>”改为“the campaign type of activity is <an object>”。这时用户就可以从规则编辑窗口的下拉列表选择 Campaign Type。 
      图 16. 营销信息 WebSphere ILog JRules 域的介绍和定制-LMLPHP

在 WebSphere ILog JRules 中定义动态域

通过在 ILog JRules Studio 的业务模型对象结构中定义和配置域,用户可以在规则编辑器中使用域来保证编辑的正确性和提供编辑的效率。但是在 ILog JRules Studio 中手动配置域这种方式需要用户花费一定的时间进行域成员的定义,规则编辑前期的工作量较大。而且当域的内容需要发生改变的时候,仍然需要用户手动进行内容的改动。如果可以动态的更新域的定义,就可以解决以上的问题,因此接下来我们将介绍如何在 ILog JRules Team Server 和 ILog JRules Studio 中定义动态域。

将动态域集成到 WebSphere ILog JRules Team Server

ILog JRules Team Server 是 ILog JRules 产品的重要组成部分,为业务人员提供协作编写、编辑、组织和搜索业务规则的指定工作空间。在这一节中我们将描述如何将动态域集成到 ILog JRules Team Server 当中。

  1. 创建一个类 Item,用于标识域中的成员结构。Name 对应 General Information 属性中的 Name 属性,verbalization 对应 Member Verbalization 属性中的 Label 属性,bomToXomMapping 对应 BOM to XOM Mapping 属性中的 Getter 的返回值。类 Item 的定义如下所示: 
    清单 1. Item 代码示例

     public class Item {

    private String name = null;
    private String verbalization = null;
    private String bomToXomMapping = null;

    }
  2. 创建一个类 DomainValueProvider 实现接口 IlrBOMDomainValueProvider。在 DomainValueProvider 继承的方法中实现以下三个方法:
    • public Collection<String> getValues(IlrClass clazz)
    • public String getDisplayText(String valueName, Locale locale)
    • public String getBOM2XOMMapping(String valueName)

    在 DomainValueProvider 中创建一个列表,用于包含 Item 对象:

    private List<Item> domainItems = new ArrayList<Item>();

    在 public Collection<String> getValues(IlrClass clazz) 中,分别根据所需要的域的内容构造 Item 对象,并把 Item 对象存入 domainItems 列表中,将 domainItems 列表中所有 Item 对象的 name 构成的集合作为 getValues 方法的返回值。IlrClass 是 BOM 结构中需要获得域的内容的类,用户可以根据这个参数,为不同的类添加不同的域的内容。public Collection<String> getValues(IlrClass clazz) 方法的内容如下所示:

    清单 2. getValues 代码示例

     public Collection<String> getValues(IlrClass clazz){
    
            // retrieve domain data from source
    // build Item according to domain data
    // add Item to domainItems list
    domainItems = buildDomains(clazz); ArrayList<String> names = new ArrayList<String>();
    if(domainItems!=null){
    Iterator<Item> it = domainItems.iterator();
    if(it!=null){
    while (it.hasNext()) {
    Item element = (Item) it.next();
    names.add(element.getName());
    } return names;
    }
    } return null;
    }

    域的值的来源可以是数据库、Web Service 等等,用户可以根据自己的需求,根据不同的域的值的来源构造 Item 对象,并将 Item 对象添加到 domainItems 列表中。在这里我们例举一个从数据库中取值构造 Item 对象的例子。

    电信运营商的数据库中包含两张表格:CampaignChannel 和 CampaignType,用于存储营销渠道和营销类型的信息,表格结构定义如下所示:

表 6. CampaignChannel 表格属性

类型描述
CHANNEL_IDVARCHAR营销渠道唯一标识
CHANNEL_NAMEVARCHAR营销渠道名称

表 7. CampaignType 表格属性

类型描述
TYPE_IDVARCHAR营销类型唯一标识
TYPE_NAMEVARCHAR营销类型名称

buildDomains 这个方法用于从数据库中读取内容,构造 Item 对象,并添加至 domainItems 列表中,从而为 WebSphere ILog JRules 动态添加域。buildDomains 方法的内容如下所示:

清单 3. buildDomains 代码示例

 public List buildDomains(IlrClass clazz){
try {
Class.forName("com.ibm.db2.jcc.DB2Driver").newInstance();
Connection connection =
DriverManager.getConnection(
"jdbc:db2://9.186.113.73:50000/CAMPAIGN",
"db2admin",
"db2admin"); String query = "";
Statement stmt = null;
ResultSet rs = null; String className = clazz.getShortDisplayName();
if("CampaignChannel".equalsIgnoreCase(className)){
query = "select CHANNEL_ID, CHANNEL_NAME from CAMPAIGNCHANNEL";
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
while(rs.next()){
String name = rs.getString("CHANNEL_ID");
String verbalization = rs.getString("CHANNEL_NAME");
String bom2xomMapping = "return '" + verbalization + "';";
Item item = new Item(name, verbalization, bom2xomMapping);
domainItems.add(item);
}
}else if("CampaignType".equalsIgnoreCase(className)){
query = "select TYPE_ID, TYPE_NAME from CAMPAIGNTYPE";
stmt = connection.createStatement();
rs = stmt.executeQuery(query);
while(rs.next()){
String name = rs.getString("TYPE_ID");
String verbalization = rs.getString("TYPE_NAME");
String bom2xomMapping = "return '" + verbalization + "';";
Item item = new Item(name, verbalization, bom2xomMapping);
domainItems.add(item);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return domainItems;
}

在 public String getDisplayText(String valueName, Locale locale) 中,根据域的 name 属性(valueName),返回域的 verbalization 属性。方法的内容如下所示:

清单 4. getDisplayText 代码示例

 public String getDisplayText(String valueName, Locale locale) {

 if(domainItems!=null){
Iterator<Item> it = domainItems.iterator();
if(it!=null){
while (it.hasNext()) {
Item element = (Item) it.next();
if (valueName.equalsIgnoreCase(element.getName())){
String verbalization = element.getVerbalization();
return verbalization;
}
}
}
} return null;
}

在 public String getBOM2XOMMapping(String valueName) 中,根据域的 name 属性(valueName),返回域的 BOM to XOM Mapping 属性。方法的内容如下所示:

清单 5. getBOM2XOMMapping 代码示例

 public String getBOM2XOMMapping(String valueName) {

 if(domainItems!=null){
Iterator<Item> it = domainItems.iterator();
if(it!=null){
while (it.hasNext()) {
Item element = it.next();
if (valueName.equalsIgnoreCase(element.getName())){
String translation = element.getTranslation();
return translation;
}
}
}
} return null;
}
  1. 将新创建的类打包成 jar,添加至 ILOG Rule Team Server.ear\teamserver.war\WEB-INF\lib 中,在服务器中更新 ILOG Rule Team Server.ear。
  2. 在 ILog JRules Studio 中为需要添加动态域的类或属性类型添加定制属性。Name 为 domainValueProviderName,Value 为 derbyDataBaseDomainProvider。
  3. 向 ILog JRules Team Server 中添加配置变量,将在 ILog JRules Studio 中添加的定制属性的值 derbyDataBaseDomainProvider 作为配置变量的 key,将创建的 DomainValueProvider 类作为配置变量的 value。 
    清单 6. 添加配置变量代码示例
     <taskdef name="set-config-param"
    classname="ilog.rules.teamserver.ant.IlrSetConfigParamTask">
    <classpath refid="teamserver-ant-tasks.classpath"/>
    </taskdef>
    <target name="set-config-param" description="" >
    <set-config-param
    appserverName="${appserver.name}"
    key="teamserver.derbyDataBaseDomainProvider"
    value="com.ibm.rule.dynamicdomain.DomainValueProvider"
    username="${rtsAdmin.login}"
    password="${rtsAdmin.password}"
    serverURL="${server.url}"
    datasourceName="${db.dataSource}"
    />
    </target>
  4. 登陆 ILog JRules Team Server 控制台,在 Project 分页中的 Business Object Model 下点击 Reload Dynamic Domains。当界面显示动态域已经成功加载后,用户就可以在 WebSphere ILog JRules Team Server 的编辑器中使用动态加载的域来编辑规则。

将动态域集成到 WebSphere ILog JRules Studio

在这一节中,我们将描述如何将动态域集成到 WebSphere ILog JRules Studio 当中。由于 ILog JRules Studio 是基于 Eclipse 平台,本节要求用户对于 Eclipse plug-in 的开发与部署有一定的了解。

    1. 创建一个插件工程 DynamicDomain。编辑工程配置属性中的 Dependencies 属性,在 Required Plug-ins 中添加 ilog.rules.studio.model。 
      图 17. 添加依赖插件 WebSphere ILog JRules 域的介绍和定制-LMLPHP
    2. 创建一个类 DomainValueProvider 实现接口 IlrBOMDomainValueProvider。在 DomainValueProvider 继承的方法中实现以下三个方法:
      • public Collection<String> getValues(IlrClass clazz)
      • public String getDisplayText(String valueName, Locale locale)
      • public String getBOM2XOMMapping(String valueName)

      具体内容见上一节中 DomainValueProvider 的介绍。

    3. 为插件工程创建一个扩展点,在配置属性的 Extensions 中添加 ilog.rules.studio.model.bomDomainValueProviders 作为工程的扩展点。设置扩展点的名称属性,并将创建的 DomainValueProvider 类作为扩展点的类。 
      图 18. 添加扩展点 WebSphere ILog JRules 域的介绍和定制-LMLPHP 

      图 19. 设置扩展点属性 WebSphere ILog JRules 域的介绍和定制-LMLPHP

    4. 将插件工程导出到 ILog JRules Studio 的 Eclipse 的安装目录下。 
      图 20. 导出插件工程 WebSphere ILog JRules 域的介绍和定制-LMLPHP
    5. 在 ILog JRules Studio 中为需要添加动态域的 BOM 对象配置定制属性。将 domainValueProviderName 作为 Property 的 Name,将在插件工程中设置的扩展点的 Name 作为 Customer Property 的 Value。
    6. 在 Domain 属性中点击 Create a domain,选择 Static references。域创建成功后,点击 Synchronize,如果显示同步成功,用户就可以在 ILog JRules Studio 当中使用动态域了。

总结

WebSphere ILOG JRules 是业界先进的业务规则管理系统,提供编写、部署和管理业务规则等业务功能。业务模型对象 (BOM) 通过提供自然语言词汇表的工具,为用户提供友好的业务规则编辑功能。域是模型对象中的重要组成部分,它对 BOM 中的类型元素设置了限制,可以帮助用户编辑、分析和检查业务规则。通过本文的介绍,用户不仅可以对 WebSphere ILog JRules 产品中域的概念有更加深入的了解,还可以通过文中描述的案例,学习如何在 WebSphere ILog JRules Studio 当中配置静态域,以及如何将动态域集成到 WebSphere ILog JRules Team Server 和 WebSphere ILog JRules Studio 当中。

声明:本文仅代表作者的个人观点,不代表 IBM 的立场。

05-04 07:18