2011年3月1日 星期二

[Oracle SOA 應用] 使用Mediator與Event處理content-based routing

這幾天剛好有個朋友問到一種在SOA設計上面常遇到的情境,使用SOA (ESB)架構做request 的content-based routing設計,常常設計出下列的composite:


這樣的設計是由SOA平台對外提供單一介面,然後根據傳入訊息內容決定要呼叫哪一個End-Point Web Service。

在SOA 11g的SCA架構中,通常是把相對應的end-point,中間的mediator與對外的web service打包成一個composite,然後一次部署上server。這樣的設計在一般情境下都非常適用,開發人員只要拖拉點選就可以快速完成。只不過,要是需求的end-point有可能有上百個的話,這張圖可能就太大了,而每一次的重新部署都會影響到所有的服務,相對應的在維護上反而造成了小小的不便。

要怎麼樣解決這樣的問題哩? 我建議可以從幾種方式下手:


  1. 使用SOA 11g內建的 EDN (Event Delivery Network)
  2. 使用BPEL Dynamic partner-link
  3. 使用BPEL + EDN + Correlation機制
這篇我們先從簡單的第一種方式開始介紹起,SOA 11g內建了EDN的機制做為各component之間訊息傳遞所用。你可以把它想像成為在SOA內部的一個JMS Server一樣的東西,你可能會問到,JMS Server不是早就有了嗎? 為什麼需要在SOA中另外設計一個EDN呢? 除了方便開發這個原因之外,我想最重要的就是避免了既然已經有一個SOA infrastructure在底層串接所有的元件,這些元件中的溝通何需另外透過JCA-based的JMS Adapter往外送出一個message,然後在另外的composite中又透過JMS Adapter抓出訊息來處理哩? 何不直接就透過SOA infrastructure來溝通就好。

這樣的架構可以供各個composite或component之間不需要【直接連接】,改用訂閱特定的event的方式來做串連,這樣的話,同樣的需求我們就可以把單一個composite拆解成多個獨立的composite:一個負責接收前端web service request,並且發出Event;另外的多個composite就各自負責聽取特定的Event,轉呼叫後端的end-point。設計如下:

1) 收request並轉發Event:


2) 收Event並轉呼叫 End-point service:



在有上百個Service end-point的情形,你只需訂一個前端的composite,在為每一種end-point設計處理使用的composite即可。這樣的de-couple架構,在特定的應用下非常有用,但是他也有相對應的壞處... 只能夠處理 One-way 的呼叫,並沒有辦法支援request-reponse的架構,要支援request-reponse架構,你可能就會需要使用到前面我們所提的另外兩種做法:dynamic partner link或是EDN + correlation的雙向Event了。

先看看怎麼定義一個Event,你會先需要有個XML Schema做為message type:


<?xml version= '1.0' encoding= 'UTF-8' ?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" 
     xmlns:eventmsg="http://blogdemo/eventmsg"
     targetNamespace="http://blogdemo/eventmsg" 
     elementFormDefault="qualified">
  <xsd:element name="EventMsg">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element name="EventID" type="xsd:string"/>
        <xsd:element name="EventContext" type="xsd:string"/>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>


這裡我們簡單使用一個EventMsg的Element做為傳遞的訊息,其中EventID供後端判斷是要哪一個end-point來處理,EventContext則定義訊息的內容。

接下來,按下composite editor上方的橘色閃電按鈕,新產生一個Event Definition File。


定義一下你的Event Definition File名稱以及他的內容的type。


當你的edl檔案定義完成之後,你就可以在component之中使用到該Event,以mediator為例,我們會需要這個mediator有個static routing rule,將傳入的event message驅動一Event。如下圖所示,你可以選擇Event按鈕之後,選擇該才所定義的Event Definition File以及Event,後續的mapping定義方式就和一般的Mediator一模一樣了。




另外,在consume Event的composite端,同樣,拉入一個mediator並double-click編輯內容,此時,在mediator routing rules中新增一個Event subscription,此時,你需要提供之前上個composite中所定義的Event Definition File,並選定你所要註冊的Event名稱。


特別注意的是,由於每一個處理Event的composite會根據EventID判斷是否此Event是自己需要處理的,因此,每一個Event subscription我們需額外定義他的subscription filter,你可以按下上圖中那個漏斗圖案進行編輯。

下圖是一個範例,指定該composite只處理EventID為1的所有事件。



相信其他的部分大家都可以自己試試看將它完成!

ps. 有興趣參考dynamic partner-link做法的人,可以參考一下這篇,該文章是10g版本的,但是差異性不大,要改成11g的作法請參考這篇

1 則留言:

華耀宗 提到...

新作上市,給你拍拍手.
~~~台新 華~~~