ZStack源碼剖析之二次開發——可擴展框架

本文首發於泊浮目的專欄: https://segmentfault.com/blog...

前言

ZStack博文-5.通用插件系統中,官方提出了幾個較爲經典的擴展方式。但在實際的二次開發中,這些作法未必可以徹底知足需求。今天筆者就和你們一塊兒來看一看一些常見的擴展方法。java

擴展是最佳選項

ZStack做爲一個開源的產品化Iaas,隨着其每一個版本的更新發布,都攜帶了極多的feature,並由其測試天團進行嚴密的測試後發佈來保證質量。同時,每一個版本也會攜帶大量的bug fix。git

若是在本身fork的ZStack中耦合了過多本身的代碼(對於Iaas的擴展或本身的業務邏輯),會致使跟不上master分支,這樣會丟失掉不少高質量feature和bug的fix。github

擴展的特殊技巧

ExtensionPoint

ZStack源碼剖析之設計模式鑑賞——三駕馬車中,筆者提到過基於觀察者模式的ExtensionPoint。其本質是經過Java的Interface來定義一系列的實現類,並收集它們來調用,這樣它們能夠散落在各個模塊中,但在Application起來時它們卻一塊兒被Spring加載到了內存中。segmentfault

利用這種方法,咱們能夠很容易的添加本身的代碼到模塊中,但又不影響主幹代碼。設計模式

在此前提上,也能夠關注代碼中的ExtensionPointEmitter,該組件也是參考了這樣的設計。框架

Flow

ZStack源碼剖析之核心庫鑑賞——FlowChain一文中,咱們瞭解到Flow是ZStack的基礎設施之一,同時也容許經過XML顯示聲明的方式來聲明Flow。所以,咱們能夠經過添加本身的Flow來執行一些本身的擴展邏輯。async

Event

基於EventFacadefire的路徑上定義接收點。如在HostBase中,定義了HOST_DELETED_PATH。咱們能夠選擇在本身的代碼模塊中註冊一個evft.on。用於執行本身的邏輯。ide

chain.done(new FlowDoneHandler(msg) {
            @Override
            public void handle(Map data) {
                casf.asyncCascadeFull(CascadeConstant.DELETION_CLEANUP_CODE, issuer, ctx, new NopeCompletion());
                bus.publish(evt);

                HostDeletedData d = new HostDeletedData();
                d.setInventory(HostInventory.valueOf(self));
                d.setHostUuid(self.getUuid());
                evtf.fire(HostCanonicalEvents.HOST_DELETED_PATH, d);
            }
        }).error(new FlowErrorHandler(msg) {
            @Override
            public void handle(ErrorCode errCode, Map data) {
                evt.setError(errf.instantiateErrorCode(SysErrors.DELETE_RESOURCE_ERROR, errCode));
                bus.publish(evt);
            }
        }).start();

Backend

這裏以KvmBackend爲例,咱們先簡單的看一下這個類模塊化

public class KvmBackend extends HypervisorBackend

HypervisorBackend繼承了HypervisorBackendHypervisorBackend繼承了SMPPrimaryStorageBaseSMPPrimaryStorageBase繼承了PrimaryStorageBase測試

咱們來看一下,KvmBackend 裏handle什麼樣的消息。

咱們能夠看到,這些Msg執行的邏輯和主存儲類型息息相關,不能以同一個PrimaryStorageBase來一律而論。所以,同一個Msg在不一樣類型的存儲、不一樣的場景下會有不同的邏輯來handle。

同理,一些ManagerImpl也能夠使用繼承進行擴展。

簡單來講,就是對基類進行擴展,覆寫那些咱們須要修改的方法。

模塊化工程

在ZStack中,有許許多多的代碼模塊。在擴展本身的業務邏輯時,最好新建一個Module用於存放本身的代碼,對於模塊和Bean的依賴能夠按需放入(相似Plugin的形式)。並結合以上的幾個方式來進行擴展。

那麼在這個過程當中,該注意哪些事項呢?

Spring的配置

在ZStack中,咱們能夠看到全部的Bean配置都是由ZStack.xml管理的,

而引用xml的地方則是這裏:

所以,咱們須要注意引入的xml是否有被配置起來。

JPA的配置

ZStack使用了Hibernate 這個ORM框架,並對映射類用XML的形式來管理。即:persistence.xml

須要注意的是,在DatabaseFacade的XML配置文件中,引用了該配置文件。所以對於這個文件的方式建議是覆寫(即再建立一個persistence.xml,用於引用ZStack中的表對象和本身的表對象),而不是再配置一個進行引用。由於這樣可能會影響主幹代碼。

保證ZStack的主幹沒有被本身的代碼影響

ZStack在Test目錄下提供了大量Case。在完成本身的擴展後(照理論上來講不該該改動ZStack的源代碼),能夠嘗試在該目錄下跑全部的Case:

mvn compile && cd test && mvn test -Dtest=ZStackTest

若是都跑過了,則證實ZStack的主幹代碼可能沒有受到影響。

小結

在本文中,筆者介紹了幾種較爲優雅的擴展方式。利用這些方法可讓咱們較爲方便的跟上主線,避免花大量精力在解決衝突上。

固然,若是你們有更好的擴展方式,也能夠在評論區補充。
相關文章
相關標籤/搜索