1. 程式人生 > >kettle 4.2原始碼分析第二講--Kettle外掛結構體系簡介

kettle 4.2原始碼分析第二講--Kettle外掛結構體系簡介

1.  外掛體系結構

1.1. 外掛技術原理

1.1.1.    外掛概念說明

  外掛是一種遵循統一的預定義介面規範編寫出來的程式,應用程式在執行時通過介面規範對外掛進行呼叫,以擴充套件應用程式的功能。在英文中外掛通常稱為plug-in、plugin或者plug in。外掛最典型的例子是Eclipse開發平臺,Microsoft的ActiveX控制元件和COM(Component Object Model,部件物件模型)實際上ActiveX控制元件不過是一個更高繼承層次的COM而已。此外還有Photoshop的濾鏡(Filter)也是一種比較常見的外掛,還有就是Mozilla Firefox,Foobar等等也遵循著外掛機制。

  外掛最吸引人的地方當然就是其所實現“執行時(Run-time)”功能擴充套件。這意味著軟體開發者可以通過公佈外掛的預定義介面規範,從而允許第三方的軟體開發者通過開發外掛對軟體的功能進行擴充套件,而無需對整個程式程式碼進行重新編譯。執行時是相對於編譯時(Assembly-time)而言的。一般來說,軟體開發者對軟體功能更新時,是在原始碼級別進行更新,然後對整個程式進行重新編譯,進而釋出應用程式的新版本,這就是編譯時的軟體更新。

  外掛的本質在於不修改程式主體(或者程式執行平臺)的情況下對軟體功能進行擴充套件與加強,當外掛的介面公開後,任何公司或個人都可以製作自己的外掛來解決一些操作上的不便或增加新的功能,也就是實現真正意義上的“即插即用”軟體開發。“平臺+外掛軟體結構”是將一個待開發的目標軟體分為兩部分,一部分為程式的主體或主框架,可定義為平臺,另一部分為功能擴充套件或補充模組,可定義為外掛。

  在進行軟體開發之前,是否採用“平臺+外掛軟體結構”進行軟體開發,還要依據具體的軟體需求情況進行確定,但一般來講,使用“平臺+外掛軟體結構”進行軟體設計會給所開發軟體增加新的生命力。當確定“平臺+外掛的軟體結構”之後,就要分析哪些部分功能由主體完成(即平臺的基本功能),哪些部分功能由外掛完成(即需要擴充套件的外掛功能)。平臺所完成的功能應為一個軟體系統的核心和基礎,這些基本功能即可為使用者使用,也可為外掛使用,就是又可以把平臺基本功能分為兩個部分,核心功能和外掛處理功能。平臺的核心功能是整個軟體的重要功能,一個軟體的大部分功能因由核心功能完成。平臺的外掛處理功能用於擴充套件平臺和管理外掛,為外掛操縱平臺和與外掛通訊提供標準平臺擴充套件介面。外掛所完成的功能是對平臺功能的擴充套件與補充,一般外掛完成系列化功能。

  為了實現平臺+外掛結構的軟體設計需要定義兩個標準介面,一個為由平臺所實現的平臺擴充套件介面,一個為外掛所實現的外掛介面。這裡需要說明的是:平臺擴充套件介面完全由平臺實現,外掛只是呼叫和使用,外掛介面完全由外掛實現,平臺也只是呼叫和使用。平臺擴充套件介面實現外掛向平臺方向的單向通訊,外掛通過平臺擴充套件介面可獲取主框架的各種資源和資料,可包括各種系統控制代碼,程式內部資料以及記憶體分配等。外掛介面為平臺向外掛方向的單向通訊,平臺通過外掛介面呼叫外掛所實現的功能,讀取外掛處理資料等。

  平臺外掛處理功能包括外掛註冊、管理和呼叫,以及平臺擴充套件介面的功能實現。外掛註冊為按照某種機制首先在系統中搜索已安裝外掛,之後將搜尋到的外掛註冊到平臺上,並在平臺上生成相應的呼叫機制,這包括選單選項、工具欄、內部呼叫等。外掛管理完成外掛與平臺的協調,為各外掛在平臺上生成管理資訊以及進行外掛的狀態跟蹤。外掛呼叫為呼叫各外掛所實現的功能。平臺外掛處理功能實現的另一部分功能為平臺擴充套件介面的具體實現。

1.1.2.    外掛介面的認識

  開發支援外掛功能的應用程式必須解決一個問題:如何在主程式與外掛間正確地互相通訊。為了在主程式與外掛之間能正確地互相通訊,應該先制定一套通訊標準,這套通訊標準就是介面,主程式與外掛只能通過制訂好的介面進行通訊。軟體開發中,介面只是定義功能並規定呼叫功能的形式,而不包含功能的實現。介面實質上是軟體模組的呼叫規範。在後續章節中我們將會介紹kettle開發的外掛中,常用的幾種通訊方式。

  就開發支援外掛功能的應用程式而言,一般來說由主程式的開發者來制訂介面,如果希望其他的開發人員能開發相關的外掛,只要公開相關介面即可。介面功能一般由外掛方實現。因為外掛的實現也要呼叫主程式的功能,所以介面功能也可能由主程式來實現。也就是說,主程式與外掛的資訊流可能是雙向的。

  介面的呼叫規範與功能實現互相分離有一個很大的優點:儘管不同的外掛開發者對同一個介面的具體實現不同,但是在主程式中對這些外掛的呼叫方式是一樣的。如果有主程式實現的介面,在不同的外掛中也可以用相同的使用方式呼叫主程式的功能。這極大的提高了應用程式的靈活性。

1.1.3.    程式結構及其執行機制

  主程式中,外掛管理部分用於管理外掛的安裝和刪除,並將所有安裝外掛的資訊儲存到適合的地方,例如儲存到登錄檔或配置檔案中。主程式啟動時,根據外掛的配置資訊載入外掛模組,然後獲得外掛的輸出函式或輸出類的指標並加以儲存,如果需要的話,可以向主程式增加介面介面元素,如選單、工具條按鈕等。在主程式中當點選與外掛相關聯的介面元素時,就會觸發外掛呼叫函式,在外掛呼叫函式中使用主函式中所儲存的外掛資訊呼叫外掛中實現的功能。在呼叫外掛輸出函式時也可以把主程式中實現的介面傳遞給外掛方。

1.2. Kettle體系結構

 

圖 2‑1 Kettle外掛架構

  Kettle分為kettle平臺、各類外掛。其中kettle平臺是整個系統的基礎,包括UI、外掛管理、元資料管理和資料整合引擎。UI顯示Spoon這個核心元件的介面,通過xul實現選單欄、工具欄的定製化,顯示外掛介面介面元素。元資料管理引擎管理ktr、kjb或者元資料庫,外掛通過該引擎獲取基本資訊。外掛管理引擎主要負責外掛的註冊。資料整合引擎負責呼叫外掛,並返回相應資訊。

1.2.1.    外掛擴充套件機制

  Kettle是眾多“可供插入的地方”(擴充套件點)和“可以插入的東西”(擴充套件)共同組成的集合體。在我們的生活中,電源接線板就是一種“擴充套件點”,很多“擴充套件”(也就是電線插頭)可以插在它上面。

  在Kettle中不管是以後的擴充套件還是系統整合的功能,本質上來講都是外掛,管理方式和執行機制是一致的。系統整合的功能點也均實現了對應的擴充套件介面,只是在插接的說明上略有不同。

  Kettle的擴充套件點包括step外掛、job entry外掛、Database外掛、Partioner外掛、debugging外掛,這裡我們重點介紹step、job entry、database外掛。暴露的擴充套件點如下表所示:

表 1 Step擴充套件介面

Java介面

基類

主要功能

StepMetaInterface

BaseStepMeta

儲存step設定資訊

驗證step設定資訊

序列化step設定資訊

提供獲取step類的方法

StepDialogInterface

BaseStepDialog

step屬性資訊配置視窗

StepInterface

BaseStep

處理rows

StepDataInterface

BaseStepData

為資料處理提高資料儲存

表 2 job entry擴充套件介面

Java介面

基類

主要功能

JobEntryInterface

JobEntryBase

儲存job entry設定資訊

序列化job entry設定資訊

提供獲取job entry類的方法

執行job entry任務

JobEntryDialogInterface

JobEntryDialog

job entry屬性資訊配置視窗

表 3 Database 擴充套件介面

Java介面

基類

主要功能

DatabaseInterface

BaseDatabaseMeta

訪問各類資料庫

1.2.2.    外掛的建立

  Kettle中的外掛包含兩部分,一是系統本身就已經實現的功能點,在原始碼目錄src中說明,如kettle-steps.xml;二是系統之外開發的外掛,在plugins目錄對應外掛目錄下的plugins.xml說明,plugins/steps/S3CsvInput/plugins.xml。

系統整合外掛定義(step為例)

                表 4 系統自帶外掛定義

內容

位置

外掛說明資訊

src/kettle-steps.xml,所有外掛集中說明

外掛原始碼

src與src-ui下,org.pentaho.di.steps.外掛名

外掛圖片

外掛說明xml中說明

外掛介面文字說明

org.pentaho.di.steps.外掛名.messages

  外掛說明資訊中包括描述資訊、類名(包括package,反射用)、父級目錄(Spoon左側欄目錄)、提示資訊和圖片資訊。Kettle使用國家化方式程式設計,所以軟體中的所有文字描述均由messages_**.properties提供。

 

圖 2‑2 系統整合外掛說明xml結構

擴充套件外掛定義

所以新開發的擴充套件外掛,均放在同一的目錄下進行管理,外掛管理模組會自動去該目錄下進行搜尋查詢。外掛目錄結構如下所示:

 

圖 2‑3 擴充套件外掛目錄結構

表 5 擴充套件外掛定義

內容

位置

外掛說明資訊

plugins/外掛型別/外掛名稱/plugin.xml

外掛原始碼

*.jar

外掛圖片

plugins/外掛型別/外掛名稱/

外掛依賴包

plugins/外掛型別/外掛名稱/

擴充套件外掛與系統整合外掛的說明內容相似,擴充套件外掛增加ID屬性和依賴屬性,同時他的目錄結構、描述資訊和提示資訊均能進行國際化配置。

 

圖 2‑4 擴充套件外掛說明xml結構

1.2.3.    外掛的註冊

  Spoon在啟動的時候會對所有外掛進行註冊,並儲存在PluginRegistry類裡面。平臺通過查詢PluginRegistry登錄檔獲取外掛資訊。Kettle安裝外掛需要進行重啟,解除安裝外掛也只需簡單的刪除plugins目錄結構下對應的檔案即可。

圖 2‑5 外掛註冊時序圖

 

圖 2‑6 plugin註冊相關的UML類圖

  PluginRegistry首選註冊本系統的外掛型別處理類,原始碼中註冊了7中型別,我們這裡僅介紹3中,並以StepPluginType為例。註冊型別處理類後,PluginRegistry按照不同的型別進行外掛搜尋(模板模式),基類BasePluginType提供了本地搜尋、jar搜尋、xml資訊搜尋3種鉤子。根據搜尋結果,按照不同的外掛型別儲存在PluginRegistry中。

1.2.4.    外掛查詢

  PluginRegistry提供了外掛查詢功能,準確的來說是外掛資訊的查詢功能。以steps在左側功能欄裡面的顯示為例,進行外掛查詢的說明。提供了getPlugins獲取指定外掛型別列表、getPlugin獲取指定成名外掛、getCateories獲取目錄結構、getClass獲取指定外掛類等方法。

 

圖 2‑7 Spoon中step列表

  左側顯示由Spoon.refreshCoreObjects()函式實現,如果選擇時trans相關的內容,將顯示所有的step外掛。流程圖如下所示:

 

圖 2‑8 spoon介面step外掛顯示流程

1.2.5.    外掛呼叫

  Kettle中呼叫外掛時,平臺通過元素管理引擎獲取對應的外掛資訊,通過反射生成外掛物件,呼叫對應的函式。Kettle以外觀模式的方式呼叫外掛,我們以雙擊某個外掛圖表,彈出對應配置介面為例進行說明,具體的轉換時呼叫將在後面進一步說明。

  Spoon介面互動相關的處理器都封裝到SpoonDelegates中,根據不同的事件型別呼叫對應的事件處理函式。UML類圖如下所示。

 

圖 2‑9 事件代理類

  SpoonStepsDelegate提供了與UI互動相關的處理事件,如複製、刪除、貼上、編輯等。雙擊某個step時會呼叫編輯功能,編輯功能是對外掛StepDialogInterface的封裝。時序圖如下:

圖 2‑10 雙擊編輯step時序圖

  雙擊是TransGraph物件註冊的時間,雙擊是根據頁面上的座標資訊獲取雙擊的stepmeta物件(來自於*.ktr)。然後,將這個物件傳給事件代理類處理,根據stepmeta物件,獲取對應的外掛類名,通過反射生成StepDialogInterface的例項並呼叫open()方法。

1.2.6.    外掛間通訊

  Kettle外掛之間天生就具有通訊共享資料的特點,kettle中最主要通訊方式是通過外掛時間共同關聯一個數據類物件的方式進行通訊;使用單例模式實現外掛間資訊共享。

  第一種方式還設計多執行緒同步的問題,在後面的章節中將會進行重點介紹。

1.2.7.    外掛生命週期

  Kettle並不能做到熱插拔,每次新增或者刪除外掛的時候都需要重啟。安裝或刪除外掛,只需要在plugins資料夾下新增或刪除對應的檔案即可。

2.  平臺體系結構

2.1. 元資料管理引擎

  元資料主要包括轉換元資料(.ktr)和Job元資料(.kjb),元資料也可以儲存在資料庫中,這裡我們主要介紹檔案儲存形式的。

  元資料管理類包括TransMeta,該類定義了一個轉換(對應一個.ktr檔案),提供了儲存和載入該檔案的方法;JobMeta類,同樣對應於一個工作(.kjb檔案),提供儲存和載入方法。StepMeta類儲存的是Step的一些公共資訊的類,每個類的具體的元資料將儲存在顯示了StepMetaInterface的類裡面。

  兩個類中主要儲存的資訊如下:

程式碼 1 TransMeta類主要屬性

複製程式碼
 1 private List<StepMeta>           steps;
 2 
 3 private List<TransHopMeta>       hops;
 4 
 5 private String              name;
 6 
 7 private Result      previousResult;//上一個jobentry的執行結果。
 8 
 9 private List<RowMetaAndData> ;//resultRows;這次trans執行後的資料結果。
10 
11 private List<ResultFile>     resultFiles;
複製程式碼

  steps欄位對應於.ktr中的<step>節點,hops欄位對應於<hop>節點。resultRows、previousResult實際上是外掛見的通訊類。

程式碼 2 JobMeta類主要屬性

複製程式碼
1 protected String name;  
2 
3 protected String filename;
4 
5 public List<JobEntryInterface> jobentries;//儲存jobentry列表
6 
7 public List<JobHopMeta> jobhops;//儲存jobentries之間的連結關係。
8 
9 public List<DatabaseMeta> databases;
複製程式碼

2.2. UI顯示

2.2.1.    TransGraph類

 

圖 3‑1 TransGraph類與顯示

  選中轉換標籤後,紅框內的編輯區物件對應org.pentaho.di.ui.spoon.trans包中的TransGraph類。

2.2.2.    JobGraph類

圖 3‑2 JobGraph與顯示

  選中Job標籤後,紅框內的編輯區物件對應org.pentaho.di.ui.spoon.job包中的JobGraph類。

2.3. 轉換執行引擎

2.3.1.    Trans類

  Trans類負責轉換執行相關的所有任務,包括轉換載入、相關外掛的例項化、初始化、執行、監視轉換執行,並把內容放置到TransInfo類中。

2.3.2.    StepInitThread類

  Step初始化執行緒包裝類,使用多執行緒,呼叫所有StepInterface實現類的Init函式。

2.3.3.    StepMetaDataCombi類

  把外掛的主要實現類全部儲存在這個類中,方便集中呼叫。

複製程式碼
 1 public class StepMetaDataCombi
 2 
 3 {
 4 
 5     public StepMeta stepMeta;
 6 
 7     public String stepname;
 8 
 9     public int    copy;
10 
11     public StepInterface     step;
12 
13     public StepMetaInterface meta;
14 
15     public StepDataInterface data;
16 
17 }
複製程式碼

2.3.4.    RunThread類

  步驟處理執行緒包裝類,這個類能夠處理異常並將其記錄到日誌中。同時,也能夠在異常發生或者執行結束後,記錄相關內容、關閉相關資源。

2.4. Job執行引擎

2.4.1.    Job類

  Job的執行類,本身實現了Thread是一個單獨的執行緒。Job entry可以是單獨的執行緒,也可以是順序執行,大多數情況都是順序執行下一步以上一步的執行結果為基礎。Job類也包括轉換載入、相關外掛的例項化、初始化、執行、監視Job執行。

轉自:http://www.cnblogs.com/wukenaihe/p/3212385.html