13.代碼中調用規則
概述
在URule Pro當中,是不能直接調用具體(tǐ)的規則文件的,我們需要先将定義好的規則文件放到知識包中,然後才可(kě)以對規則文件進行(xíng)測試和(hé)調用。
在代碼中調用知識包,需要先通(tōng)過KnowledgeService接口可(kě)獲取指定的知識包ID對應的構建好的資源包信息,然後通(tōng)過知識包來(lái)創建具體(tǐ)的KnowledgeSession對象,接下來(lái)插入相關業務對象,最後執行(xíng)具體(tǐ)的規則調用。
KnowledgeService接口源碼如下:
package com.bstek.urule.runtime.service;
import java.io.IOException;
import com.bstek.urule.runtime.KnowledgePackage;
/**
* @author Jacky.gao
* @since 2015年1月28日
*/
public interface KnowledgeService {
public static final String BEAN_ID="urule.knowledgeService";
/**
* 根據給定的資源包ID獲取對應的KnowledgePackage對象
* @param packageId 項目名稱加資源包ID,格式為(wèi):projectName/packageId
* @return 返回與給定的資源包ID獲取對應的KnowledgePackage對象
* @throws IOException
*/
KnowledgePackage getKnowledge(String packageId) throws IOException;
/**
* 根據給定的一個(gè)或多(duō)個(gè)資源包ID獲取對應的KnowledgePackage對象的集合
* @param packageIds 資源包ID數(shù)組
* @return 返回與給定的一個(gè)或多(duō)個(gè)資源包ID獲取對應的KnowledgePackage對象集合
* @throws IOException
*/
KnowledgePackage[] getKnowledges(String[] packageIds) throws IOException;
}
可(kě)以看到,這個(gè)接口中有(yǒu)兩個(gè)方法可(kě)供使用,一個(gè)是給一個(gè)知識包ID(格式為(wèi):projectName/packageId)返回一個(gè)對應的KnowledgePackage對象;另一個(gè)是給一個(gè)或多(duō)個(gè)知識包ID,返回一個(gè)集合類型的KnowledgePackage對象。在URule Pro當中,對于一個(gè)知識包,在使用時(shí)引擎會(huì)将其構建成KnowledgePackage對象,在這個(gè)KnowledgePackage對象中包含了所有(yǒu)由向決策集、決策表、交叉決策表、決策樹(shù)、評分卡、複雜評分卡以及決策流等文件構建的RuleSet對象,以及由規則流構成的FlowDefinition對象。
在使用getKnowledge方法獲取某個(gè)指定的package時(shí),要給一個(gè)資源包ID,需要注意的是資源包的ID在定義要要包含資源包所在項目名稱,格式為(wèi):projectName/packageId
通(tōng)過KnowledgeService接口獲取到KnowledgePackage對象後,接下來(lái)就可(kě)通(tōng)過KnowledgePackage對象創建com.bstek.urule.runtime.KnowledgeSession對象,這個(gè)對象就是引擎提供的與業務數(shù)據交互的接口,通(tōng)過這個(gè)接口,可(kě)将需要的業務數(shù)據對象插入到引擎當中,最後根據需要執行(xíng)規則或規則流。
package com.bstek.urule.runtime;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import com.bstek.urule.runtime.agenda.AgendaFilter;
import com.bstek.urule.runtime.response.FlowExecutionResponse;
import com.bstek.urule.runtime.response.RuleExecutionResponse;
import com.bstek.urule.runtime.rete.ReteInstance;
public interface KnowledgeSession extends WorkingMemory{
/**
* 執行(xíng)當前WorkMemory中所有(yǒu)滿足條件的規則
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules();
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)過濾執行(xíng)
* @param filter 對滿足條件的規則進行(xíng)過濾
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(AgendaFilter filter);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)過濾執行(xíng),并向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param parameters 向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param filter 對滿足條件的規則進行(xíng)過濾
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)執行(xíng),并定義執行(xíng)的最大(dà)數(shù)目,超出後就不再執行(xíng)
* @param max 執行(xíng)規則的最大(dà)數(shù)目
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(int max);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)執行(xíng),并定義執行(xíng)的最大(dà)數(shù)目,超出後就不再執行(xíng),<br>
* 并向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param parameters 向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param max 執行(xíng)規則的最大(dà)數(shù)目
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(Map<String,Object> parameters,int max);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)過濾執行(xíng),并定義執行(xíng)數(shù)目的最大(dà)值
* @param filter 對滿足條件的規則進行(xíng)過濾
* @param max 執行(xíng)規則的最大(dà)數(shù)目
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(AgendaFilter filter,int max);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)過濾執行(xíng),并定義執行(xíng)數(shù)目的最大(dà)值,<br>
* 并向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param parameters 向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param filter 對滿足條件的規則進行(xíng)過濾
* @param max 執行(xíng)規則的最大(dà)數(shù)目
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter,int max);
/**
* 對當前WorkMemory中所有(yǒu)滿足條件的規則進行(xíng)執行(xíng),并向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param parameters 向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則執行(xíng)耗時(shí),滿足條件的規則,執行(xíng)的規則等信息
*/
RuleExecutionResponse fireRules(Map<String,Object> parameters);
/**
* 根據規則流ID,執行(xíng)目标規則流
* @param processId 要執行(xíng)的規則流ID
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則流執行(xíng)耗時(shí)信息
*/
FlowExecutionResponse startProcess(String processId);
/**
* 根據規則流ID,執行(xíng)目标規則流,并向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @param processId 要執行(xíng)的規則流ID
* @param parameters 向WorkingMemory中設置一個(gè)Map的參數(shù)對象
* @return 返回一個(gè)ExecutionResponse對象,其中包含規則流執行(xíng)耗時(shí)信息
*/
FlowExecutionResponse startProcess(String processId,Map<String,Object> parameters);
/**
* 執行(xíng)将日志(zhì)信息寫入到日志(zhì)文件操作(zuò),要看到日志(zhì)文件我們需要設置urule.debugToFile屬性值為(wèi)true,<br>
* 同時(shí)定義輸出文件目錄屬性urule.defaultHtmlFileDebugPath,這樣在urule.debug屬性為(wèi)true情況下就會(huì)向這個(gè)目錄下寫入日志(zhì)文件,<br>
* 需要的時(shí)候,可(kě)以通(tōng)過實現com.bstek.urule.debug.DebugWriter接口定義自己的日志(zhì)輸出文件,這樣就可(kě)以将日志(zhì)輸出到任何地方
* @throws IOException 抛出IO異常
*/
void writeLogFile() throws IOException;
/**
* @return 返回對應的知識包集合
*/
List<KnowledgePackage> getKnowledgePackageList();
/**
* @return 返回Rete實例對象集合
*/
List<ReteInstance> getReteInstanceList();
/**
* @return 返回當前緩存的KnowledgeSession Map對象
*/
Map<String,KnowledgeSession> getKnowledgeSessionMap();
/**
* @return 返回當前KnowledgeSession的父,如果不存在則返回null
*/
KnowledgeSession getParentSession();
}
可(kě)以看到KnowledgeSession接口擴展自WorkingMemory接口,WorkingMemory接口源碼如下:
package com.bstek.urule.runtime;
import java.util.List;
import java.util.Map;
import com.bstek.urule.runtime.log.LogManager;
import com.bstek.urule.runtime.rete.Context;
public interface WorkingMemory{
/**
* 插入一個(gè)業務數(shù)據對象,對應到規則當中就是一個(gè)變量對象
* @param fact 目标業務數(shù)據對象
* @return 插入是否成功
*/
boolean insert(Object fact);
/**
* 更新一個(gè)在當前WorkingMemory中已存在的業務對象,如果對象存在,那(nà)麽WorkingMemory會(huì)重新評估這個(gè)對象
* @param fact 要更新的對象
* @return 更新是否成功,如果對象不在WorkingMemory中,則返回false
*/
boolean update(Object fact);
/**
* 獲取當前WorkingMemory中的某個(gè)參數(shù)值
* @param key 參數(shù)對應的key值
* @return 返回具體(tǐ)的值
*/
Object getParameter(String key);
/**
* @return 返回所有(yǒu)的參數(shù)對象
*/
Map<String,Object> getParameters();
/**
* @return 返回當前WorkingMemory中所有(yǒu)類型的業務數(shù)據對象
*/
Map<String,Object> getAllFactsMap();
/**
* @return 返回插入到當前WorkingMemory中所有(yǒu)業務對象
*/
List<Object> getFactList();
/**
* 根據knowledgePackageWrapper的id返回對應的KnowledgeSession對象
* @param id knowledgePackageWrapper的id
* @return 對應的KnowledgeSession對象
*/
KnowledgeSession getKnowledgeSession(String id);
/**
* 将KnowledgeSession對象放入緩存以備下次調用時(shí)使用
* @param id knowledgePackageWrapper的id
* @param session 對應的KnowledgeSession對象
*/
void putKnowledgeSession(String id,KnowledgeSession session);
/**
* 向當前Session中放入變量
* @param key 變量Key
* @param value 變量值
*/
void setSessionValue(String key,Object value);
/**
* 取出當前Session中對應的變量
* @param key 變量key
* @return 變量值
*/
Object getSessionValue(String key);
/**
* @return 返回當前SessionValueMap對象
*/
Map<String,Object> getSessionValueMap();
/**
* 激活某個(gè)設置了互斥組屬性的具體(tǐ)的規則
* @param activationGroupName 互斥組屬性值
* @param ruleName 規則名
*/
void activeRule(String activationGroupName,String ruleName);
/**
* 激活指定名稱的執行(xíng)組
* @param groupName 執行(xíng)組名稱
*/
void activePendedGroup(String groupName);
/**
* 激活指定名稱的執行(xíng)組并立即執行(xíng)執行(xíng)組規則對應的動作(zuò)部分
* @param groupName 執行(xíng)組名稱
*/
void activePendedGroupAndExecute(String groupName);
/**
* 返回當前上(shàng)下文對象
* @return 返回當前上(shàng)下文對象
*/
Context getContext();
/**
* @return 返回當前LogManager對象
*/
LogManager getLogManager();
/**
* @return 返回當前FactManager對象
*/
FactManager getFactManager();
}
要通(tōng)過KnowledgePackage對象或這個(gè)對象的數(shù)組創建一個(gè)KnowledgeSession對象,可(kě)以通(tōng)過com.bstek.urule.runtime.KnowledgeSessionFactory類中下面兩個(gè)靜态方法實現:
/**
* 創建一個(gè)普通(tōng)的KnowledgeSession對象
* @param knowledgePackage 創建KnowledgeSession對象所需要的KnowledgePackage對象
* @return 返回一個(gè)新的KnowledgeSession對象
*/
public static KnowledgeSession newKnowledgeSession(KnowledgePackage knowledgePackage){
return new KnowledgeSessionImpl(knowledgePackage);
}
/**
* 創建一個(gè)普通(tōng)的KnowledgeSession對象
* @param knowledgePackage 創建KnowledgeSession對象所需要的KnowledgePackage集合對象
* @return 返回一個(gè)新的KnowledgeSession對象
*/
public static KnowledgeSession newKnowledgeSession(KnowledgePackage[] knowledgePackages){
return new KnowledgeSessionImpl(knowledgePackages);
}
單次調用
由于這兩個(gè)方法都是靜态方法,所以可(kě)以直接調用,下面的代碼中演示了完整的調用過程:
package tt;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
* @author Jacky.gao
* @since 2015年3月5日
*/
public class Invoke {
public void doTest() throws Exception{
//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通(tōng)過KnowledgeService接口獲取指定的資源包"projectName/test123"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
//通(tōng)過取到的KnowledgePackage對象創建KnowledgeSession對象
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
Employee employee=new Employee();
Dept dept=new Dept();
dept.setLevel(12);
employee.setDept(dept);
employee.setSalary(111000);
//将業務數(shù)據對象Employee插入到KnowledgeSession中
session.insert(employee);
//執行(xíng)所有(yǒu)滿足條件的規則
session.fireRules();
}
}
在上(shàng)面的示例當中,獲取到KnowledgeSession對象後,向其中插入一個(gè)名為(wèi)Employee業務數(shù)據對象,這樣引擎在計(jì)算(suàn)時(shí),會(huì)直接采用Employee中相關數(shù)據,如有(yǒu)條件滿足,同時(shí)有(yǒu)對Employee中相關數(shù)據賦值,那(nà)麽會(huì)直接反映到當前插入的這個(gè)Employee對象當中。
在實際使用中,可(kě)能還(hái)會(huì)向KnowledgeSession中添加參數(shù)數(shù)據(以Map形式添加),對應URule中的參數(shù)庫文件中定義的信息,引擎計(jì)算(suàn)完成後,我們要通(tōng)KnowledgeSession中的getParameter來(lái)獲取具體(tǐ)的參數(shù)對象,而不 能通(tōng)過原添加的Map中獲取,如下代碼:
package tt;
import java.util.HashMap;
import java.util.Map;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
* @author Jacky.gao
* @since 2015年3月5日
*/
public class Invoke {
public void doTest() throws Exception{
//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通(tōng)過KnowledgeService接口獲取指定的資源包"test123"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
//通(tōng)過取到的KnowledgePackage對象創建KnowledgeSession對象
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
Employee employee=new Employee();
Dept dept=new Dept();
dept.setLevel(12);
employee.setDept(dept);
employee.setSalary(111000);
//将業務數(shù)據對象Employee插入到KnowledgeSession中
session.insert(employee);
//執行(xíng)所有(yǒu)滿足條件的規則
Map<String,Object> parameter=new HashMap<String,Object>();
parameter.put("count", 10);
parameter.put("result", true);
//觸發規則時(shí)并設置參數(shù)
session.fireRules(parameter);
//獲取計(jì)算(suàn)後的result值,要通(tōng)過KnowledgeSession,而不能通(tōng)過原來(lái)的parameter對象
boolean result=(Boolean)session.getParameter("result");
System.out.println(result);
}
}
從上(shàng)面的代碼中可(kě)以看到,在規則計(jì)算(suàn)完成後,在獲取計(jì)算(suàn)後的參數(shù)中的result值時(shí),我們并沒有(yǒu)用提供參數(shù)的parameter,而是通(tōng)過KnowledgeSession的getParameter來(lái)實現,這是因為(wèi)在向KnowledgeSession設置參數(shù)時(shí),引擎會(huì)将參數(shù)中所有(yǒu)的值取出并放入到引擎中內(nèi)置的一個(gè)Map中,以避免影(yǐng)響原參數(shù)的值。所以計(jì)算(suàn)完成後,我們要通(tōng)過KnowledgeSession的getParameter來(lái)獲取計(jì)算(suàn)後的參數(shù)值。
如果我們的資源包中包含有(yǒu)規則流,那(nà)麽在插入好相關業務數(shù)據對象後,可(kě)以通(tōng)過KnowledgeSession中提供的startProcess來(lái)實現規則流的調用,如下面的代碼所示:
package tt;
import java.util.HashMap;
import java.util.Map;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
* @author Jacky.gao
* @since 2015年3月5日
*/
public class Invoke {
public void doTest() throws Exception{
//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通(tōng)過KnowledgeService接口獲取指定的資源包"test123"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
//通(tōng)過取到的KnowledgePackage對象創建KnowledgeSession對象
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
Employee employee=new Employee();
Dept dept=new Dept();
dept.setLevel(12);
employee.setDept(dept);
employee.setSalary(111000);
//将業務數(shù)據對象Employee插入到KnowledgeSession中
session.insert(employee);
//執行(xíng)所有(yǒu)滿足條件的規則
Map<String,Object> parameter=new HashMap<String,Object>();
parameter.put("count", 10);
parameter.put("result", true);
//開(kāi)始規則流并設置參數(shù)
session.startProcess("flow-test",parameter);
//獲取計(jì)算(suàn)後的result值,要通(tōng)過KnowledgeSession,而不能通(tōng)過原來(lái)的parameter對象
boolean result=(Boolean)session.getParameter("result");
System.out.println(result);
}
}
在URule Pro當中,規則流中是不存在人(rén)工任務的,也就是說規則流的執行(xíng)是一次性完成的,這點與包含人(rén)工任務的工作(zuò)流引擎不同,比如UFLO,在UFLO中有(yǒu)人(rén)工任務,所以開(kāi)啓流程實例後可(kě)能需要多(duō)次完成人(rén)工任務才能完成一個(gè)流程實例。
使用GeneralEntity傳遞值
在代碼中調用知識包,對于需要插入到規則中的變量對象,可(kě)能當前環境裏并不存在,或者說這種變量的屬性是動态可(kě)變的,對于這兩種我們可(kě)以使用URule Pro中提供的GeneralEntity來(lái)代替實際的業務對象。
GeneralEntity擴展自HashMap,所以可(kě)以通(tōng)過Map的put方法将目标對象的屬性及其值在代碼中逐個(gè)填入,同時(shí)GeneralEntity實例化時(shí)要求必須要提供一個(gè)String類型的構造參數(shù),這個(gè)String類型的值表示的就是目标業務對象的完整類名。 上(shàng)面的通(tōng)過startProcess來(lái)實現規則流的調用代碼示例,通(tōng)過使用GeneralEntity來(lái)代替實際業務對象,代碼就是下面的樣子:
package tt;
import java.util.HashMap;
import java.util.Map;
import com.bstek.urule.Utils;
import com.bstek.urule.model.GeneralEntity;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
* @author Jacky.gao
* @since 2015年3月5日
*/
public class Invoke {
public void doTest() throws Exception{
//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通(tōng)過KnowledgeService接口獲取指定的資源包"test123"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
//通(tōng)過取到的KnowledgePackage對象創建KnowledgeSession對象
KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
GeneralEntity employee=new GeneralEntity("rete.test.Employee");
GeneralEntity dept=new GeneralEntity("rete.test.Dept");
dept.setLevel(12);
employee.setDept(dept);
employee.setSalary(111000);
//将業務數(shù)據對象Employee插入到KnowledgeSession中
session.insert(employee);
//執行(xíng)所有(yǒu)滿足條件的規則
Map<String,Object> parameter=new HashMap<String,Object>();
parameter.put("count", 10);
parameter.put("result", true);
//開(kāi)始規則流并設置參數(shù)
session.startProcess("flow-test",parameter);
//獲取計(jì)算(suàn)後的result值,要通(tōng)過KnowledgeSession,而不能通(tōng)過原來(lái)的parameter對象
boolean result=(Boolean)session.getParameter("result");
System.out.println(result);
}
}
在上(shàng)面的代碼當中,我們就通(tōng)過GeneralEntity來(lái)代替實際的Employee和(hé)Dept對象插入到規則當中,運行(xíng)後我們發現其結果與實際的Employee和(hé)Dept對象插入到規則當中運行(xíng)結果完全一緻。
實際上(shàng),在URule Pro提供的快速測試、基于JSON的快速測試、防真測試三種測試工具中以及Rest服務裏,實際在調用規則傳遞變量時(shí)采用的都是GeneralEntity來(lái)代替實際的業務對象, 所以如果我們在代碼中調用業務規則實際業務對象不存在時(shí),也可(kě)以采用GeneralEntity實現業務數(shù)據的傳遞。
批處理(lǐ)支持
實際業務當中,我們除了會(huì)做(zuò)單條規則計(jì)算(suàn)外,還(hái)有(yǒu)可(kě)能需要運行(xíng)規則引擎來(lái)處理(lǐ)一大(dà)批數(shù)據,這些(xiē)數(shù)據可(kě)能有(yǒu)幾萬條,幾十萬條,甚至更多(duō)。在這種情況下,如果我們還(hái)是采用普通(tōng)的KnowledgeSession在一個(gè)線程裏處理(lǐ)大(dà)批量數(shù)據的話(huà),那(nà)麽引擎還(hái)是隻能在當前線程裏運行(xíng),這樣就會(huì)需要很(hěn)長的時(shí)間(jiān)才能可(kě)能将這幾十萬條甚至更多(duō)的數(shù)據處理(lǐ)完成,在這個(gè)時(shí)候,為(wèi)了充分利用服務器(qì)較強的CPU性能,我們可(kě)以使用BatchSession利用多(duō)線程并行(xíng)處理(lǐ)這些(xiē)數(shù)據。顧名思義BatchSession是用來(lái)做(zuò)批處理(lǐ)任務的會(huì)話(huà)對象,它是 URule Pro當中提供的多(duō)線程并行(xíng)處理(lǐ)大(dà)批量業務數(shù)據的規則會(huì)話(huà)對象。
要得(de)到一個(gè)BatchSession對象,我們也需要提供一個(gè)或多(duō)個(gè)KnowledgePackage對象,獲取KnowledgePackage對象的方法與上(shàng)面介紹的方法相同,有(yǒu)了KnowledgePackage對象後,就可(kě)以利用KnowledgeSessionFactory類創建一個(gè)BatchSession對象。
在com.bstek.urule.runtime.KnowledgeSessionFactory類中除上(shàng)面提到的兩個(gè)構建KnowledgeSession的靜态方法外,還(hái)提供了另外八個(gè)可(kě)用于構建BatchSession的靜态方法,其源碼如下:
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,這裏默認将開(kāi)啓10個(gè)普通(tōng)的線程池來(lái)運行(xíng)提交的批處理(lǐ)任務,默認将每100個(gè)任務放在一個(gè)線程裏處理(lǐ)
* @param knowledgePackage 創建BatchSession對象所需要的KnowledgePackage對象
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSession(KnowledgePackage knowledgePackage){
return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,第二個(gè)參數(shù)來(lái)指定線程池中可(kě)用線程個(gè)數(shù),默認将每100個(gè)任務放在一個(gè)線程裏處理(lǐ)
* @param knowledgePackage 創建BatchSession對象所需要的KnowledgePackage對象
* @param threadSize 線程池中可(kě)用的線程個(gè)數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSessionByThreadSize(KnowledgePackage knowledgePackage,int threadSize){
return new BatchSessionImpl(knowledgePackage,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,這裏默認将開(kāi)啓10個(gè)普通(tōng)的線程池來(lái)運行(xíng)提交的批處理(lǐ)任務,第二個(gè)參數(shù)用來(lái)決定單個(gè)線程處理(lǐ)的任務數(shù)
* @param knowledgePackage 創建BatchSession對象所需要的KnowledgePackage對象
* @param batchSize 單個(gè)線程處理(lǐ)的任務數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSessionByBatchSize(KnowledgePackage knowledgePackage,int batchSize){
return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,第二個(gè)參數(shù)來(lái)指定線程池中可(kě)用線程個(gè)數(shù),第三個(gè)參數(shù)用來(lái)決定單個(gè)線程處理(lǐ)的任務數(shù)
* @param knowledgePackage 創建BatchSession對象所需要的KnowledgePackage對象
* @param threadSize 線程池中可(kě)用的線程個(gè)數(shù)
* @param batchSize 單個(gè)線程處理(lǐ)的任務數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSession(KnowledgePackage knowledgePackage,int threadSize,int batchSize){
return new BatchSessionImpl(knowledgePackage,threadSize,batchSize);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,這裏默認将開(kāi)啓10個(gè)普通(tōng)的線程池來(lái)運行(xíng)提交的批處理(lǐ)任務,默認将每100個(gè)任務放在一個(gè)線程裏處理(lǐ)
* @param knowledgePackage 創建BatchSession對象所需要的KnowledgePackage集合對象
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages){
return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,第二個(gè)參數(shù)來(lái)指定線程池中可(kě)用線程個(gè)數(shù),默認将每100個(gè)任務放在一個(gè)線程裏處理(lǐ)
* @param knowledgePackages 創建BatchSession對象所需要的KnowledgePackage集合對象
* @param threadSize 線程池中可(kě)用的線程個(gè)數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSessionByThreadSize(KnowledgePackage[] knowledgePackages,int threadSize){
return new BatchSessionImpl(knowledgePackages,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,這裏默認将開(kāi)啓10個(gè)普通(tōng)的線程池來(lái)運行(xíng)提交的批處理(lǐ)任務,第二個(gè)參數(shù)用來(lái)決定單個(gè)線程處理(lǐ)的任務數(shù)
* @param knowledgePackages 創建BatchSession對象所需要的KnowledgePackage集合對象
* @param batchSize 單個(gè)線程處理(lǐ)的任務數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSessionByBatchSize(KnowledgePackage[] knowledgePackages,int batchSize){
return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
}
/**
* 創建一個(gè)用于批處理(lǐ)的BatchSession對象,第二個(gè)參數(shù)來(lái)指定線程池中可(kě)用線程個(gè)數(shù),第三個(gè)參數(shù)用來(lái)決定單個(gè)線程處理(lǐ)的任務數(shù)
* @param knowledgePackages 創建BatchSession對象所需要的KnowledgePackage集合對象
* @param threadSize 線程池中可(kě)用的線程個(gè)數(shù)
* @param batchSize 單個(gè)線程處理(lǐ)的任務數(shù)
* @return 返回一個(gè)新的BatchSession對象
*/
public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages,int threadSize,int batchSize){
return new BatchSessionImpl(knowledgePackages,threadSize,batchSize);
}
前面介紹規則流中的決策節點時(shí),了解到決策節點中支持百分比分流,這種百分比分流就要求必須是在使用BatchSession處理(lǐ)一批數(shù)據的時(shí)候,或者是一個(gè)用一個(gè)普通(tōng)的KnowledgeSession一次性處理(lǐ)多(duō)條數(shù)據才有(yǒu)效,否則規則流隻會(huì)走比例最高(gāo)的那(nà)個(gè)分支。
BatchSession接口比較簡單,它隻定義了兩個(gè)方法:
/**
* 添加一個(gè)具體(tǐ)要執行(xíng)Business對象
* @param business Business對象實例
*/
void addBusiness(Business business);
/**
* 等待線程池中所有(yǒu)業務線程執行(xíng)完成,在進行(xíng)批處理(lǐ)操作(zuò)時(shí)一定要以此方法作(zuò)為(wèi)方法調用結尾
*/
void waitForCompletion();
可(kě)以看到,它可(kě)以接收若幹個(gè)名為(wèi)com.bstek.urule.runtime.Business接口實例,Business接口比較簡單,它隻有(yǒu)一個(gè)方法:
package com.bstek.urule.runtime;
/**
* @author Jacky.gao
* @since 2015年9月29日
*/
public interface Business {
void execute(KnowledgeSession session);
}
在Business實現類中,我們的業務寫在execute方法當中,在這個(gè)方法中,隻有(yǒu)一個(gè)KnowledgeSession對象,這個(gè)session對象就是我們與規則引擎操作(zuò)的對象,示例代碼如下:
//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通(tōng)過KnowledgeService接口獲取指定的資源包"aaa"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/aaa");
//通(tōng)過取的KnowledgePackage對象創建BatchSession對象,在這個(gè)對象中,我們将開(kāi)啓5個(gè)線程,每個(gè)線程最多(duō)放置10個(gè)Bussiness接口實例運行(xíng)
BatchSession batchSession=KnowledgeSessionFactory.newBatchSession(knowledgePackage, 5, 10);
for(int i=0;i<100;i++){
batchSession.addBusiness(new Business(){
@Override
public void execute(KnowledgeSession session) {
Employee employee=new Employee();
employee.setSalary(11080);
//将業務數(shù)據對象Employee插入到KnowledgeSession中
session.insert(employee);
session.startProcess("demo");
}
});
}
//等待所有(yǒu)的線程執行(xíng)完成,對于BatchSession調用來(lái)說,此行(xíng)代碼必不可(kě)少(shǎo),否則将導緻錯誤
batchSession.waitForCompletion();
其它API
這裏羅列了幾個(gè)非常用的api,這些(xiē)api涉及到操作(zuò)知識庫裏的文件、操作(zuò)知識包、查看文件引用等相關api,這裏羅列出來(lái),我們可(kě)以根據業務需要,通(tōng)過調用這些(xiē)api可(kě)實現在業務系統中操作(zuò)知識包或知識庫裏的文件等。
這些(xiē)接口實現都配置在Spring當中,如果我們需要在業務代碼中調用這些(xiē)接口方法,那(nà)麽可(kě)以通(tōng)過Spring的ApplicationContext引用它們,比如要使用RepositoryService接口,那(nà)麽可(kě)以通(tōng)過下面的代碼獲取RepositoryService接口 在Spring中的對象實例引用:
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(RepositoryService.BEAN_ID);
上(shàng)面的代碼中的RepositoryService.BEAN_ID是一個(gè)定義在RepositoryService接口中的靜态常量,用于表示它在Spring中定義的Bean的ID。其實不僅是RepositoryService接口, 後面要介紹除了RefactorService(RefactorService對象實例要通(tōng)過RepositoryService接口中getRefactorService()方法獲取)外, ReferenceService、KnowledgePackageRepositoryService等都有(yǒu)一個(gè)名為(wèi)BEAN_ID的靜态常量,也都可(kě)以通(tōng)過它來(lái)獲取它們在Spring中定義的Bean的ID值。
RepositoryService
RepositoryService接口中定義了針對知識庫文件操作(zuò)的大(dà)部分方法,其源碼如下:
package com.bstek.urule.console.repository;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import com.bstek.urule.console.Principal;
import com.bstek.urule.console.repository.model.FileType;
import com.bstek.urule.console.repository.model.RepositoryFile;
import com.bstek.urule.console.repository.refactor.Item;
import com.bstek.urule.console.repository.refactor.RefactorService;
public interface RepositoryService extends RepositoryReader{
public static final String BEAN_ID="urule.repositoryService";
/**
* @param filePath 文件路徑
* @return 返回文件是否存在
* @throws Exception 抛出異常
*/
boolean fileExistCheck(String filePath) throws Exception;
/**
* @param projectName 項目名稱
* @param user 創建人(rén)
* @param classify 是否采用分類方式返回創建好的項目結果
* @return 返回創建好的項目結果對象RepositoryFile
* @throws Exception 抛出異常
*/
RepositoryFile createProject(String projectName,Principal user,boolean classify) throws Exception;
/**
* 創建目錄
* @param path 新目錄的路徑
* @param user 創建人(rén)
* @throws Exception 抛出異常
*/
void createDir(String path,Principal user) throws Exception;
/**
* 創建文件
* @param path 文件路徑
* @param content 文件內(nèi)容
* @param user 創建人(rén)
* @throws Exception 抛出異常
*/
void createFile(String path,String content,Principal user) throws Exception;
/**
* 保存文件
* @param path 文件路徑
* @param content 文件內(nèi)容
* @param newVersion 是否以版本形式保存
* @param versionComment 版本內(nèi)容,如果不是以版本形式保存,這裏給null即可(kě)
* @param user 保存文件的用戶
* @throws Exception 抛出異常
*/
void saveFile(String path,String content,boolean newVersion,String versionComment,Principal user) throws Exception;
/**
* 删除文件
* @param path 要删除的文件路徑
* @param user 操作(zuò)的用戶
* @throws Exception 抛出異常
*/
void deleteFile(String path,Principal user)throws Exception;
/**
* 鎖定指定文件
* @param path 文件路徑
* @param user 操作(zuò)的用戶
* @throws Exception 抛出異常
*/
void lockPath(String path,Principal user) throws Exception;
/**
* 解鎖文件
* @param path 文件路徑
* @param user 操作(zuò)的用戶
* @throws Exception 抛出異常
*/
void unlockPath(String path,Principal user) throws Exception;
/**
* 加載項目
* @param project 項目名
* @param user 操作(zuò)的用戶,會(huì)根據這個(gè)用戶權限過濾加載後的文件
* @param classify 返回的項目是否以分類形式展示
* @param types 要加載的文件類型
* @param searchFileName 要搜索的文件文件名
* @return 返回項目的Repository對象
* @throws Exception 抛出異常
*/
Repository loadRepository(String project,Principal user,boolean classify,FileType[] types,String searchFileName) throws Exception;
/**
* 文件重命名
* @param path 文件原路徑
* @param newPath 新路徑
* @throws Exception 抛出異常
*/
void fileRename(String path, String newPath) throws Exception;
/**
* 将指定項目以xml形式導出
* @param projectPath 要導出項目
* @param outputStream 導入後的項目要輸出的目的地
* @throws Exception 抛出異常
*/
void exportXml(String projectPath,OutputStream outputStream)throws Exception;
/**
* 導出所有(yǒu)項目
* @param outputStream 導入後要輸出的目的地
* @throws Exception 抛出異常
*/
void exportXml(OutputStream outputStream)throws Exception;
/**
* 導入xml文件
* @param inputStream要導入的xml的數(shù)據源
* @param overwrite 是否覆蓋已存在的項目
* @throws Exception 抛出異常
*/
void importXml(InputStream inputStream,boolean overwrite)throws Exception;
/**
* @param project 項目名稱
* @return 返回指定項目的目錄信息
* @throws Exception 抛出異常
*/
List<RepositoryFile> getDirectories(String project) throws Exception;
/**
* @param project 項目名
* @param all 是否返回所有(yǒu)的客戶端配置信息,包含<b>禁用</b>狀态的客戶信息
* @return 返回客戶端信息列表
* @throws Exception 抛出異常
*/
List<ClientConfig> loadClientConfigs(String project,boolean all)throws Exception;
/**
* @param path 項目路徑
* @return 返回項目名,會(huì)去除項目名前可(kě)能存在的/
*/
String getProject(String path);
/**
* @return 返回項目中配置的ClientProvider接口實現,如果有(yǒu)的話(huà)
*/
ClientProvider getClientProvider();
/**
* 重構庫文件內(nèi)容
* @param path 是重構的庫文件路徑
* @param item 要重構的內(nèi)容
* @throws Exception 抛出異常
*/
void refactorContent(String path,Item item) throws Exception;
/**
* @param path 文件路徑
* @return 返回文件是否存在
* @throws Exception 抛出異常
*/
boolean fileExist(String path) throws Exception;
/**
* @param project 指定的項目
* @param principal 操作(zuò)人(rén)
* @return 返回指定項目中所有(yǒu)的變量庫文件內(nèi)容信息列表
* @throws Exception 抛出異常
*/
List<ProjectVariable> loadProjectLibraries(String project,Principal principal) throws Exception;
/**
* @return 返回當前的RefactorService實例對象
*/
RefactorService getRefactorService();
}
RepositoryService接口擴展自RepositoryReader,在RepositoryReader接口中定義了一些(xiē)用于讀取知識庫文件的相關操作(zuò),其源碼如下:
package com.bstek.urule.console.repository;
import java.io.InputStream;
import java.util.List;
import com.bstek.urule.console.repository.model.RepositoryFile;
import com.bstek.urule.console.repository.model.VersionFile;
public interface RepositoryReader {
/**
* 加載指定的companyId下創建的所有(yǒu)的項目信息
* @param companyId 指定的公司ID
* @return 返回所有(yǒu)的項目信息
* @throws Exception 抛出異常
*/
List<RepositoryFile> loadProjects(String companyId) throws Exception;
/**
* 讀取指定的最新版本的文件
* @param path 文件考路徑
* @return 返回文件內(nèi)容
* @throws Exception 抛出異常
*/
InputStream readFile(String path) throws Exception;
/**
* 獲取指定路徑文件的所有(yǒu)版本信息
* @param path 文件路徑
* @return 返回版本信息列表
* @throws Exception 抛出異常
*/
List<VersionFile> getVersionFiles(String path) throws Exception;
/**
* 讀取指定版本文件
* @param path 文件路徑
* @param version 文件版本号
* @return 返回文件內(nèi)容
* @throws Exception 抛出異常
*/
InputStream readFile(String path, String version) throws Exception;
}
RefactorService
RefactorService的作(zuò)用是用于實現對規則文件名以及庫文件中定義的信息值的重命名操作(zuò),也就是我們通(tōng)常說的重構操作(zuò)。RefactorService接口比較特殊, 它的實例要通(tōng)過RepositoryService接口中提供的getRefactorService()方法獲取,RefactorService接口源碼如下:
package com.bstek.urule.console.repository.refactor;
import com.bstek.urule.console.repository.Repository;
public interface RefactorService {
/**
* 重構文件名操作(zuò),路徑要以jcr:開(kāi)頭
* @param oldPath 舊(jiù)路徑
* @param newPath 新路徑
* @throws Exception 抛出異常
*/
void refactorFile(String oldPath,String newPath) throws Exception;
/**
* 重構指定Repository下所有(yǒu)文件,路徑要以jcr:開(kāi)頭
* @param oldPath 舊(jiù)路徑
* @param newPath 新路徑
* @param repo 指定的Repository
* @throws Exception 抛出異常
*/
void refactorFile(String oldPath,String newPath,Repository repo) throws Exception;
/**
* 重構某個(gè)變量庫文件或常量庫文件或參數(shù)庫文件或動作(zuò)庫文件下某具體(tǐ)值
* @param path 具體(tǐ)值所在庫文件路徑,路徑要以jcr:開(kāi)頭
* @param item 要重構的庫文件內(nèi)容的具體(tǐ)值
* @throws Exception 抛出異常
*/
void refactorItem(String path,Item item) throws Exception;
}
ReferenceService
顧名思義,ReferenceService接口作(zuò)用是用于查看庫文件以及庫文件定義在其它文件中引用的接口,基實例定義在Spring中,在Spring中的Bean的ID為(wèi)ReferenceService.BEAN_ID, ReferenceService接口源碼如下:
package com.bstek.urule.console.repository.reference;
import java.util.List;
public interface ReferenceService {
public static final String BEAN_ID="urule.referenceService";
/**
* @param path 被引用的文件路徑
* @param item 包含的內(nèi)容對象
* @return 返回引用了當前庫文件指定內(nèi)容的其它文件列表
* @throws Exception 抛出異常
*/
List<RefFile> loadReferenceFiles(String path,SearchItem item) throws Exception;
/**
* @param path 被引用的文件路徑
* @return 返回引用了當前文件的其它文件列表
* @throws Exception 抛出異常
*/
List<RefFile> loadReferenceFiles(String path) throws Exception;
}
KnowledgePackageRepositoryService
KnowledgePackageRepositoryService操作(zuò)的對象是定義在項目中的知識包對象,基實例定義在Spring中,在Spring中的Bean的ID為(wèi)KnowledgePackageRepositoryService.BEAN_ID,其源碼如下:
package com.bstek.urule.console.repository;
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import com.bstek.urule.console.repository.model.ResourcePackage;
import com.bstek.urule.console.repository.model.VersionFile;
import com.bstek.urule.model.library.variable.VariableCategory;
import com.bstek.urule.runtime.KnowledgePackage;
public interface KnowledgePackageRepositoryService {
/**
* 根據指定格式的知識包信息,獲取當前知識包的所有(yǒu)已發布的版本信息
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @return 返回所有(yǒu)已發布的知識包版本集合信息
*/
List<VersionFile> getKnowledgePackges(String packageInfo);
/**
* 返回已發布的知識包指定版本對應的文件信息
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的知識包版本
* @return 返回對應的文件信息Map
*/
Map<String,Object> loadKnowledgePackageFiles(String packageInfo,String version);
/**
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @return 返回已發布的當前處于激活狀态下的知識包的版本信息
*/
VersionFile getActivedKnowledgePackge(String packageInfo);
/**
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
* @return 返回對應版本的已發布的知識包編譯後的byte信息
*/
byte[] getKnowledgePackgeBytes(String packageInfo,String version);
/**
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
* @return 返回對應版本的已發布的知識包編譯後的KnowledgePackage對象信息
*/
KnowledgePackage getKnowledgePackge(String packageInfo,String version);
/**
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
* @return 返回對應版本的已發布的知識包中包含的變量庫信息集合
*/
List<VariableCategory> getKnowledgePackgeLib(String packageInfo,String version);
/**
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
* @return 返回對應版本的已發布的知識包編譯後的InputStream對象信息
*/
InputStream getKnowledgePackgeData(String packageInfo,String version);
/**
* 删除指定版本已發布的知識包信息
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
*/
void removeKnowledgePackge(String packageInfo,String version);
/**
* 删除指定知識所有(yǒu)已發布的知識包信息
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
*/
void removeDeployKnowledgePackge(String packageInfo);
/**
* 将指定版本的已發布的知識包定義為(wèi)處于激活狀态的知識包
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param version 指定的已發布的版本
*/
void activeKnowledgePackage(String packageInfo,String version);
/**
* 修改指定知識的狀态,将狀态改為(wèi)<b>停用</b>或<b>啓用</b>
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param state true表示<b>啓用</b>,false表示<b>停用</b
*/
void knowledgePackageStateChange(String packageInfo,boolean state);
/**
* 項目重命名時(shí)觸發修改當前項目下知識包的存儲路徑
* @param oldName 舊(jiù)項目名
* @param newName 新項目名
*/
void projectRename(String oldName,String newName);
/**
* 重置知識包時(shí)間(jiān)戳
* @param project 項目名稱
*/
void resetProjectResourcePackagesTag(String project);
/**
* @param project 項目名稱
* @return 返回指定項目的知識包時(shí)間(jiān)戳
*/
String getProjectResourcePackagesTag(String project);
/**
* @param project 項目名稱
* @return 返回指定項目的知識包信息集合
*/
List<ResourcePackage> loadProjectResourcePackages(String project);
/**
* @param file 要查找的文件
* @return 返回包含當前文件的知識包列表
*/
List<ResourcePackage> loadResourcePackagesByFile(String file);
/**
* 發布一個(gè)新的知識包版本
* @param packageInfo 知識包信息,格式為(wèi):項目名/知識包ID,如:testProject/testPackage
* @param knowledgePackage 發布的編譯後知識包對象
* @param comment 知識包版本備注
* @param createUser 發布人(rén)
* @param active 是否激活
*/
void saveKnowledgePackage(String packageInfo,KnowledgePackage knowledgePackage,String comment,String createUser,boolean active);
}
AuthorityRepositoryService
AuthorityRepositoryService接口實現針對規則項目及文件的權限配置操作(zuò),基實例定義在Spring中,在Spring中的Bean的ID為(wèi)AuthorityRepositoryService.BEAN_ID,其源碼如下:
package com.bstek.urule.console.repository.authority;
import java.util.List;
import com.bstek.urule.console.Principal;
import com.bstek.urule.console.repository.OperateType;
public interface AuthorityRepositoryService {
/**
* 保存授權信息
* @param p 當前操作(zuò)的登錄對象信息
* @param user 要授權的對象的用戶名
* @param authority 要授權的信息
* @param type 操作(zuò)類型
* @throws Exception 抛出異常
*/
void saveAuthority(Principal p,String user,Authority authority,OperateType type) throws Exception;
/**
* 加載指定companyId下所有(yǒu)的權限信息
* @param companyId 指定的companyId,應與當前登錄用戶的companyId保持一緻
* @return 返回權限信息集合
* @throws Exception 抛出異常
*/
List<AuthorityUnit> loadAuthorityUnits(String companyId) throws Exception;
/**
* 重置某個(gè)companyId下對應的權限信息的時(shí)間(jiān)戳,系統內(nèi)部調用
* @param companyId 指定的companyId
* @return 返回新的重置後的時(shí)間(jiān)戳
* @throws Exception 抛出異常
*/
long resetAuthorityTag(String companyId) throws Exception;
/**
* 檢查指定companyId下權限信息有(yǒu)沒有(yǒu)變化,系統內(nèi)部調用
* @param companyId 指定的companyId
* @param timestamp 給定的時(shí)間(jiān)戳
* @return 如果有(yǒu)變化返回新的時(shí)間(jiān)戳,沒變化則返回0
* @throws Exception 抛出異常
*/
long check(String companyId,long timestamp) throws Exception;
/**
* 保存權限信息文件,系統內(nèi)部調用
* @param content 文件xml格式內(nèi)容
* @param user 保存操作(zuò)的調用人(rén)
* @return 返回保存後的時(shí)間(jiān)戳
* @throws Exception 抛出異常
*/
long saveAuthoritiesFile(String content,Principal user) throws Exception;
}
RepositoryInteceptor
RepositoryInteceptor接口的作(zuò)用是攔截對所有(yǒu)規則文件的的添加、修改、删除操作(zuò),實現好該接口後配置到spring中即可(kě)生(shēng)效,其源碼內(nèi)容如下:
package com.bstek.urule.console;
public interface RepositoryInteceptor {
void readFile(String file);
void saveFile(String file,String content);
void createFile(String file,String content);
void deleteFile(String file);
void renameFile(String oldFileName,String newFileName);
void createDir(String dir);
void createProject(String project);
}
KnowledgePackagePublishListener
KnowledgePackagePublishListener接口是用來(lái)攔截發布知識包操作(zuò),實現好該接口後配置到spring中即可(kě)生(shēng)效,其源碼內(nèi)容如下:
package com.bstek.urule.console.servlet.respackage;
import com.bstek.urule.runtime.KnowledgePackage;
public interface KnowledgePackagePublishListener {
void beforePublish(String packageId,String comment,boolean active);
void afterPublish(KnowledgePackage knowledgePackage,String comment,boolean active);
void beforeActive(String packageId,String version);
void afterActive(KnowledgePackage knowledgePackage,String version);
}