使用WEBLOGIC PORTAL規則引擎中實現動態商務邏輯

來源:互聯網
上載者:User
web|動態

  簡介

  業務應用的需求總是隨著業務環境的變化趨勢而不斷地改變。決策很少是一成不變的,並且競爭壓力要求商務邏輯的設計和實現具有靈活性,以快速地適應不斷變化的需求。通常,對商務邏輯的更改必須由開發人員來完成,然後進行多次徹底的測試,而這將是一個很耗時的過程。在應用程式的修改工作完成後,需要將其重新部署到伺服器,需要留出預定的停機時間,以防應用程式對使用者不可用。

  對於這個問題,更好的解決方案是通過應用程式之外的一組規則來實現某些業務決策。這些規則並沒有被編譯到應用程式中,而是在運行時讀取並應用。通過這種方式,無需更改代碼或者停止正在啟動並執行應用程式就可以改變這些規則。

  WebLogic Portal包括一個基本的規則引擎,用於使WebLogic Platform應用程式從規則獲益。儘管該引擎不是功能完備的產品,但我們將展示如何將其與WebLogic Integration Business Processes (JPDs)一起使用來為商務邏輯提供一種靈活且動態實現機制,從而無需只為了修改規則而重新部署應用程式。

  首先我們來看一下將在全文中使用的應用程式範例,然後介紹如何將規則引擎注入到WLI流程中以實現商務邏輯。然後,我們將更仔細地研究這些規則本身以及如何為商務邏輯定義這些規則,最後將描述在運行中的系統中更改商務規則所使用的機制。

  應用程式範例

  我們將開發一個樣本交易應用程式作為在商務程序中使用規則的例子。該交易應用程式是一個金融交易流程的簡化版本,該流程使用調用規則引擎的JPD商務程序而構建。該應用程式範例採用了不同的有價證券交易集合,並根據一組由業務定義的規則將其分組成交易塊以便執行,或許是為了減少傭金。當然,這裡給出的應用程式並不完整,但它已經足以展示如何在現實世界應用程式中使用規則引擎。有完整的原始碼可供下載,其中的readme檔案提供了構建和運行該應用程式的說明。

  在解釋如何開發這樣的應用程式之前,我們先通過對門戶規則引擎的一些特性的簡要概括來瞭解其工作方式。這裡假定讀者熟悉一般的規則技術。

  規則引擎及其工作方式

  圖1說明了規則引擎的基本情況。該引擎根據一組規則來處理初始的事實集,而這些規則由引擎從外部庫中獲得。初始事實用於為該引擎填充工作記憶體。由規則來對工作記憶體中的事實進行評估,如果滿足某條規則的條件,則將執行對應的動作。通常,一個規則動作將向工作記憶體中添加一條新的事實,並重複該流程直到應用完所有的規則。然後通過可選的過濾器來選擇特定類的對象以返回給調用方。可以通過Controls介面訪問規則引擎,還可以用它來設定屬性(比如規則集檔案的位置)。

  圖1:該規則引擎是一個由控制項封裝的EJB。儲存庫中的規則反覆地應用於工作記憶體中的事實,以獲得新的事實。在無法進行繼續推理的情況下,對工作記憶體進行過濾以返回感興趣的項目。

  從WLI流程調用規則引擎

  讓我們從被實現為JPD的交易商務程序開始,來看看如何添加對規則引擎的調用。要在WLI流程中添加規則,可以使用作為WebLogic Portal的一部分而提供的Rules Executor Control(規則執行器控制項)。對於本例,我們只使用該控制項中所提供的方法和特性的一個子集。關於規則控制項的附加說明文檔可以在參考資料部分找到。

  此處假定開發人員使用WebLogic Workshop整合式開發環境來建立新的流程應用程式。然後可在該應用程式中建立一個流程項目。因為預設情況下門戶控制項在流程項目中不可用,所以需要將這些控制項和規則引擎的EJB匯入到應用程式。然後,將控制項輸入和輸出插入到JPD中。在WLI流程中使用門戶規則引擎的基本步驟如下:

  匯入規則引擎到應用程式:

  • 在應用程式中包含規則引擎。
  • 將p13n_controls庫添加到應用程式。

  處理輸入和輸出:

  • 為輸入和結果添加變數。
  • 建立一個Rules Executor控制項。
  • 在WLI流程中添加一個Control Send With Return節點。
  • 為建立初始資料編寫Java代碼。
  • 添加一個流程節點以對結果進行迭代。
  • 建立規則集。

  後面我們將更詳細地討論其中的每一個步驟。

  在應用程式中包含規則引擎

  規則引擎包含在下面的檔案中:

  /weblogic81/p13n/lib/p13n_ejb.jar

  要在應用程式中包含該引擎,請右擊Workshop整合式開發環境中的Modules檔案夾,並選擇Add Module。導航到該jar檔案,並選擇Open。

  將p13n_controls庫添加到應用程式

  要使得門戶規則控制項在應用程式中可用,請右擊Workshop整合式開發環境中的Libraries檔案夾,並選擇Add Library。該控制項位於:

  </weblogic81/p13n/lib/p13n_controls.jar

  導航到此檔案,單擊 Open 按鈕。

  為輸入和結果添加變數

  這裡使用的Rules Executor控制項方法需要一個對象數組作為輸入並返回一個結果的迭代器。在Workshop整合式開發環境中為這些值建立變數,這樣我們就可以在下一步中通過圖形化使用者介面來建立控制項。要完成該任務,請為Data Palette中的變數單擊Add按鈕,鍵入輸入變數的名稱,並鍵入Java類型java.lang.Object[]。使用同樣的方式建立Java類型為java.util.Iterator的輸出變數。

  建立一個Rules Executor控制項

  要建立規則控制項,請單擊Data Palette中控制項的Add按鈕。從菜單中選擇Portal Controls -> Rules Executor。為控制項鍵入名稱,並按下Create按鈕。

  在WLI流程中添加一個Control Send With Return節點

  將剛剛建立的控制項拖放到流程中以建立一個控制項節點來實際調用規則引擎。在樣本中,我們將使用控制項的evaluateRuleSet()方法。從Send Data面板中,選擇前面為方法的輸入參數而建立的輸入變數。使用Receive Data面板選擇返回變數來擷取規則執行的結果。在Property Editor視窗中為控制項屬性鍵入相應的值。

  為建立初始資料編寫Java代碼

  在建立了輸入變數後,我們還沒有對它賦值,所以需要編寫代碼來完成該任務。這個變數是一個Java對象數組,它提供了輸入到規則條件中的初始事實。可以建立一個新的Perform節點來初始化該數組,或者通過使用Source View在Control Send節點中添加代碼來設定該變數的值。

  添加一個流程節點以對結果進行迭代

  Rules Executor控制項的每一個計算方法都將返回一個結果的迭代器。編寫代碼,使用該值實現對規則執行結果的迭代。如果沒有指定過濾器類,這個迭代器將返回規則引擎工作記憶體中的所有值。其中包括原始輸入以及任何在執行滿足條件的規則的動作時添加到工作記憶體中的值。對於添加的對象,迭代器返回一個Result類的對象,該類的getObject()方法可以返回在規則動作中所添加的實際對象。

  建立規則集

  使用XML編輯器,在/META-INF/data目錄中建立一個副檔名為.rls的檔案。規則通常添加到子目錄rulesets中。

  商務邏輯規則

  我們剛剛展示了如何在商務程序中插入規則引擎。現在讓我們來看看如何利用該規則引擎以及如何編寫映射到商務規則的規則。

  規則包括兩個部分:應用該規則時必須為真的條件,以及當條件滿足時將執行的動作。因此,要在應用程式中使用規則,設計人員必須首先定義哪些對象和屬性在測試規則條件時對規則編寫者是可見的。規則引擎允許在一個條件中調用任意多個方法。這種構造方式便於定義JavaBean作為組成初始事實集合的對象,規則引擎使用這些初始事實來進行推理。可以使用bean的 get方法來獲得條件測試的值。

  規則所引用的Java對象需要從建立它的WLI流程以及從規則引擎本身中都可見。這就避免了這些對象與流程JPD位於同一包中,更確切地說,它們應該被建立於作為同一應用程式的一部分的Java項目中。然後,這些對象可以通過package.class標記在規則檔案(.rls)和流程JPD中引用。

  在我們的交易樣本中,將把不同的交易分組以便可以成塊執行。為實現該目標,我們定義兩個bean來表示相關的對象。第一個是Trade bean,它表示單個的交易訂單。這個bean的屬性工作表示交易的份額、股份數目以及所期望的價格等。任何對於決定證券交易所屬的塊來說可能有用的值,都應該作為這個具有公有get方法的bean的屬性,以便能夠在規則中使用它。第二個bean是Block bean,通過它可以儲存所有根據某個屬性集彙總在一起的不同交易。這個bean的屬性包括規則中任何可用於判定塊大得足以執行訂單的的資訊。這些屬性可以是平均價格、交易的總美元數或總的份額數等等。

  為了在我們的應用程式中實現塊功能,首先使用規則來定義某項交易是否只需要執行其自身就足夠了(也就是說,它是僅包含單個交易的塊),或者如果不是這樣的話,那麼應該使用什麼屬性將其與其他交易聚集以形成一個塊。在一項交易聚集到適當的塊中後,就會第二次調用規則引擎來判斷該塊是否完成。例如,假設我們想要得到這樣的規則:

  • 規則1:任何5,000股及以上的單項交易應該作為一個塊並予以執行。
  • 規則2:由同一個投資管理者定購的具有相同標記的交易應該聚集在一起。
  • 規則3:總價值超過,000的塊應該予以執行。

  調用與規則條件中的對象相關聯的方法很容易,如下面的樣本所示,這是規則1的條件:

<cr:conditions>  <greater-than-or-equal-to>    <instance-method>      <variable>        <type-alias>Beans.Trade</type-alias>      </variable>      <name>getQuantity</name>      <!-- getQuantity (and any other bean property) takes           no arguments.  If it did, they           would go here        <arguments>...</arguments>      -->    </instance-method>    <literal:integer>      5000    </literal:integer>  </greater-than-or-equal-to></cr:conditions>

  在這個樣本中,如果在我們的事實中有一個Trade對象,那麼規則引擎就會調用它的getQuantity()方法並且將結果與整型5000進行比較。如果它大於或等於5000,則該條件為真。

  規則的第二部分是條件滿足時執行的動作的列表。最常見的動作是:建立一個新對象,把它添加到規則引擎用來評分準則的事實集中。規則引擎繼續對規則進行迭代,直到無法從事實中得出更多的推理;向動作添加新對象會導致另一輪的條件評估迴圈。正如我們將要看到的那樣,可以建立任意類型的對象,並定義對應用程式具有特定意義的各種類型。這裡的技巧是,應用程式設計者可以定義一組足夠豐富的動作,以包含那些可由規則編寫者調用以滿足各種業務需求的任務。

  在我們的交易應用程式樣本中,所有動作都會建立將添加到由規則引擎使用的工作集中的新對象。有些規則向該集合中添加簡單的String對象。這些對象表示了從原始事實中演繹出來的中間事實,它們可以在規則引擎中得到進一步的推理,但流程JPD不會以任何形式解釋它們。其他的規則將建立Beans.Action類的對象。這些對象包括當規則條件滿足時流程將執行的實際命令。流程JPD和支援類將實施已知的動作命令來聚集交易並執行塊交易。在這個簡單的樣本中,實際上只有兩個已知的命令:建立(並執行)訂單、使用指定的屬性聚集一項交易。前面規則2的動作是使用屬性symbol和manager來進行聚集,該動作如下:

<cr:actions>  <new-instance>    <type-alias>Beans.Action</type-alias>    <arguments>      <literal:string>symbol, manager</literal:string>    </arguments>  </new-instance></cr:actions>

  響應該動作,流程JPD及其支援類為當前交易查詢symbol和投資manager,找出具有相同的symbol和投資manager的未執行交易,並將這些交易聚集到相同的塊。

  在完成一項交易的聚集後,將從第二個Rules Executor控制項再次調用規則引擎,以評估規則,決定是否應該執行產生的塊交易。根據商務規則3,該規則如下:

<cr:conditions>  <greater-than >    <instance-method>      <variable>        <type-alias>Beans.Block</type-alias>      </variable>      <name>getAmount</name>    </instance-method>    <literal:float>      50000.00    </literal:float>  </greater-than ></cr:conditions><cr:actions>  <new-instance>    <type-alias>Beans.Action</type-alias>    <arguments>      <literal:string>create</literal:string>    </arguments>  </new-instance></cr:actions>

  這一次,我們分析Beans.Block對象,擷取amount屬性並與閾值進行比較。如果該條件滿足,則使用create命令向工作集中添加一個Beans.Action對象,這是通知流程執行該塊訂單的訊號。

  讓我們仔細分析一下流程JPD。下面有用於調用規則引擎的Control Send節點的代碼。正如我們可以看到的,該節點使用一個Rules Executor控制項來評估規則集,該控制項返回一個迭代器。通過其屬性(沒有給出),控制項將過濾結果,僅返回Beans.Action類的對象。通過這些對象,代碼將提取動作命令並執行所請求的動作。正如前面所提到的,如果動作是聚集該交易,則流程將使用更新後的塊作為輸入,對規則引擎開始第二次調用。通過執行適當的動作,對結果進行第二次迭代迴圈。

public void rulesExecutorControlEvaluateRuleSet()    throws Exception{    // Execute the Rules using facts as the input     //#START: CODE GENERATED - PROTECTED SECTION - you can safely      // Add code above this comment in this method. #//    // Input transform    // Return method call    this.results =        rulesExecutorControl.evaluateRuleSet(this.facts);    // Output transform    // Output assignments    //#END  : CODE GENERATED - PROTECTED SECTION - you can safely       // Add code below this comment in this method. #//    /* Iterate over the results of rules execution. This assumes that       results are filtered to return only items of the Beans.Action class.         The command property from the Action is expected to be either the       string "create," in which case a Block trade can be executed from       the single discrete Trade, or it is expected to be a list of       attributes describing the Block that this Trade should be        incorporated into.     */    while (results.hasNext())    {        String action =             ((Action)results.next()).getCommand();        if (action.equals("create"))            (new Block(trade)).execute();  // single-trade               else        {            // Aggregate trade into an intermediate Block            trade.aggregate(blockStorage, action);                          /* Call the rules engine a second time, this time using             the resulting Block as the only input.  This is to             determine if the resulting Block now meets the criteria              to execute the order. Again, results are assumed to be             filtered by the control to return only the Actions.            */            Block block = trade.getBlock();            Object blockFacts[] = new Object[1];            blockFacts[0] = block;            Iterator blockResults =                 blockRulesCntl.evaluateRuleSet(blockFacts);            while (blockResults.hasNext())            {              action =                 ((Action)blockResults.next()).getCommand();              if (action.equals("create"))                  block.execute();            }        }    }}

  動態規則

  WebLogic Portal的特性之一是Datasync功能,通過它可以將修改後的資料重新部署到叢集中的門戶應用程式中。因為門戶規則引擎從Datasync儲存區中獲得其規則檔案,所以應用程式的商務規則可以在啟動並執行系統中變更,而無需停止應用程式。關於Datasync以及用於更新資料的Datasync Web應用程式的其他資訊,請參閱WebLogic Portal文檔。

  預設情況下,Datasync Web應用程式將部署在常規門戶應用程式中。然而,我們的應用程式範例是一個WLI流程應用程式,因此必須在其中手動地包含Datasync。要在Workshop整合式開發環境中完成這些工作,請右擊Modules檔案夾,並選擇Add Module。然後,選擇下面的檔案:

  /weblogic81/p13n/lib/datasync.war

  在叢集中,Datasync應用程式應該僅部署到管理伺服器。

  為了闡明如何在運行中的應用程式中更改規則,應用程式範例中包括了兩個不同的規則檔案,這兩個檔案中包括了用於將交易聚整合塊的可選規則。前面已經描述了預設規則(定義於traderules.rls檔案中),第二個集合(在altrules.rls中)定義如下規則:

  • 按照標記將所有的交易聚整合塊。
  • 執行包含3,000或更多股的塊。

  要看到動態規則的執行,首先使用所提供的測試資料運行應用程式範例。無需停止伺服器或者重新部署應用程式,直接將原始規則儲存到一個新檔案中,並將替代的規則檔案從:

  /META-INF/data/rulesets/altrules.rls

  拷貝到:

  /META-INF/data/rulesets/traderules.rls

  再次運行樣本資料,這時會發現產生了不同的訂單。

  注意,在樣本域中不需要重新運行Datasync Web應用程式來更新規則。這是因為樣本平台域以開發模式運行。在這種模式下,Datasync自動輪詢 /META-INF/data目錄及其子目錄以搜尋更改,更改過的檔案可以自動地重新部署到應用程式。在生產域中,需要使用Web應用程式來實現資料的重新部署。推薦的步驟是,首先為所有更新過的檔案建立一個jar檔案,jar檔案的根目錄應該是data。然後,使用Datasync Web應用程式的Bootstrap Data功能來重新部署套件含了新規則的jar檔案。

  下載

  您可以下載本文中使用的樣本程式的原始碼:SampleApp.zip (2MB)

  結束語

  在與WLI流程應用程式一起使用時,Portal Rules Engine是實現商務邏輯的強大工具。它很容易合并到WLI流程中,並且可以使用JavaBean來評估規則條件,或者擴充作為規則評估結果而執行的動作。最後,Datasync特性所提供的動態更新能力使得商務邏輯更靈活,並能夠在不改變Java代碼的前提下適應不斷變化的需求,所以不需要重新部署應用程式。



相關文章

Beyond APAC's No.1 Cloud

19.6% IaaS Market Share in Asia Pacific - Gartner IT Service report, 2018

Learn more >

Apsara Conference 2019

The Rise of Data Intelligence, September 25th - 27th, Hangzhou, China

Learn more >

Alibaba Cloud Free Trial

Learn and experience the power of Alibaba Cloud with a free trial worth $300-1200 USD

Learn more >

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。