Floodlight-Main.java 分析

Floodlight 的 Main 解析圖


需要理解的概念

模塊(Module)

Module 是指繼承了 IFloodlightModule 接口的類

IFloodlightModule的相關(guān)注釋

 Defines an interface for loadable Floodlight modules.
 At a high level, these functions are called in the following order:
 
  getModuleServices() : 獲得模塊實現(xiàn)的服務(wù)列表
  getServiceImpls(); 實例化并返回:服務(wù)實現(xiàn)類-實現(xiàn)此服務(wù)的對象 映射
  getModuleDependencies() : 獲得模塊依賴的列表
  init() : internal initializations (<em>don't</em> touch other modules)
  startUp() : external initializations (<em>do</em> touch other modules)

所有可加載的模塊都有這幾種方法,在接下來的加載模塊時需要使用到席舍。
每個具體的模塊都會重寫這幾個函數(shù)布轿,下面舉個 FloodlightProvider 的例子。

getModuleServices()

@Override
public Collection<Class<? extends IFloodlightService>> getModuleServices() {
    Collection<Class<? extends IFloodlightService>> services =
            new ArrayList<Class<? extends IFloodlightService>>(1);
    services.add(IFloodlightProviderService.class);
    return services;
}

獲得 FloodlightProvider 的服務(wù) IFloodlightProviderService

getServiceImple()

@Override
public Map<Class<? extends IFloodlightService>,
           IFloodlightService> getServiceImpls() {
    controller = new Controller();

    Map<Class<? extends IFloodlightService>,
        IFloodlightService> m =
            new HashMap<Class<? extends IFloodlightService>,
                        IFloodlightService>();
    m.put(IFloodlightProviderService.class, controller);
    return m;
}

返回服務(wù)實現(xiàn)類和實現(xiàn)用的對象的Map来颤。

getModuleDependencies()

@Override
public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
    Collection<Class<? extends IFloodlightService>> dependencies =
        new ArrayList<Class<? extends IFloodlightService>>(4);
    dependencies.add(IStorageSourceService.class);
    dependencies.add(IPktInProcessingTimeService.class);
    dependencies.add(IRestApiService.class);
    dependencies.add(IDebugCounterService.class);
    dependencies.add(IOFSwitchService.class);
    dependencies.add(IThreadPoolService.class);
    dependencies.add(ISyncService.class);
    return dependencies;
}

返回依賴的列表

其他

init(),startup()汰扭,到對應(yīng)的模塊去看就可以了。
有的模塊是沒有服務(wù)依賴的福铅,比如 ThreadPool模塊萝毛。

服務(wù)(Service)

Service 是指繼承了 IFloodlightService 接口的類。

public abstract interface IFloodlightService {
   // This space is intentionally left blank....don't touch it
}

模塊使用getModuleServices()方法可以獲得對應(yīng)的服務(wù)列表滑黔,可以到源碼去看對應(yīng)的服務(wù)功能笆包。

Main函數(shù)

  1. 解析命令行參數(shù)
  2. 加載模塊
  3. 啟動 REST 服務(wù)器
  4. 啟動 Controller

命令行參數(shù)解析

CmdLineSetting 定義了命令行參數(shù)的格式

public static final String DEFAULT_CONFIG_FILE = "src/main/resources/floodlightdefault.properties";

@Option(name="-cf", aliases="--configFile", metaVar="FILE", usage="Floodlight configuration file")
private String configFile = DEFAULT_CONFIG_FILE;

如果沒有使用-cf指定配置文件路徑环揽,則使用默認(rèn)路徑“src/main/resources/floodlightdefault.properties”

CmdLineParser 解析命令參數(shù)

CmdLineParser parser = new CmdLineParser(settings)
parser.parserArgument(args)

加載模塊

moduleContext=fml.loadModulesFromConfig(settings.getModuleFile())
settings.getModuleFile()提供配置文件的路徑

mergeProperties()

  • 目的是獲得配置文件里的模塊的集合configMods和prop是除去配置文件里的模塊鍵值對后剩余的配置信息(模塊的配置參數(shù))

loadModulesFromList(configsMods,prop)

findAllModule(configMods)
  • 填充moduleNameMap,moduleServiceMap,ServiceMap

這個方法比較重要的是這個 ServiceLoader,返回服務(wù)加載器

ServiceLoader<IFloodlightModule> moduleLoader =
            ServiceLoader.load(IFloodlightModule.class, cl);

ServiceLoader 為了注冊服務(wù)庵佣,需要在類路徑 src/main/resources/META_INF/services文件夾內(nèi)列好注冊服務(wù)的模塊歉胶,可以得到繼承了 IFloodlightModule 接口的實現(xiàn)類

使用moduleLoader.iterator()迭代器去填充moduleNameMap,moduleServiceMap,ServiceMap

moduleNameMap 模塊名稱-模塊對象 Map
moduleServiceMAP 模塊名稱-模塊服務(wù) Map
ServiceMap 模塊服務(wù)-模塊名稱 Map

traverseDeps(moduleName,modsToLoad,moduleList,moduleMap,modsVisited)
addModule()
  • 添加模塊到模塊的哈希集moduleMap,同時注冊它們的服務(wù)(即得到已加載模塊序列 moduleList)
parseConfigParameters(prop)
  • 解析每個模塊的配置參數(shù)

取配置文件的一條參數(shù)配置net.floodlightcontroller.forwarding.Forwarding.match=in-port, vlan, mac, ip, transport舉例

key:net.floodlightcontroller.forwarding.Forwarding.match

String configKey=key.substring(LastPeriod+1)

獲到的就是 match,即 configKey=match

String systemKey = System.getProperty(key);
if (systemKey != null) {
            configValue = systemKey;
        } else {
            configValue = prop.getProperty(key);
        }

如果系統(tǒng)屬性已經(jīng)存在秧了,則使用系統(tǒng)屬性的值跨扮,如果不存在,則configValue = prop.getProperty(key);【即 configValue 在此處為in-port, vlan, mac, ip, transport】

floodlightModuleContext.addConfigParam(mod,configKey,configValue)
  • 添加模塊的配置參數(shù)

FloodlightModuleLoader 類下的方法

public void addConfigParam(IFloodlightModule mod, String key, String value) {
    Map<String, String> moduleParams = configParams.get(mod.getClass());
    if (moduleParams == null) {
        moduleParams = new HashMap<String, String>();
        configParams.put(mod.getClass(), moduleParams);
    }
    moduleParams.put(key, value);
}
initModules(moduleList)
  • 初始化已加載模塊列表下的模塊

獲得模塊的服務(wù)實例

Map<Class<? extends IFloodlightService>,
            IFloodlightService> simpls = module.getServiceImpls();

添加服務(wù)到 floodlightModuleContext

if (floodlightModuleContext.getServiceImpl(s.getKey()) == null) {
                    floodlightModuleContext.addService(s.getKey(),
                                                       s.getValue());

遍歷已加載模塊集验毡,開始初始化模塊衡创,調(diào)用模塊的方法:init

for (IFloodlightModule module : moduleSet) {
        // init the module
        if (logger.isDebugEnabled()) {
            logger.debug("Initializing " +
                         module.getClass().getCanonicalName());
        }
        module.init(floodlightModuleContext);
    }
startupModules(moduleList)
  • 調(diào)用已加載模塊的啟動方法

遍歷已加載模塊集,調(diào)用每個模塊的啟動方法

for (IFloodlightModule m : moduleSet) {
        if (logger.isDebugEnabled()) {
            logger.debug("Starting " + m.getClass().getCanonicalName());
        }
        m.startUp(floodlightModuleContext);
    }
return floodlightModuleContext

返回公共環(huán)境變量

fml.runModules()

  • 運動控制器模塊和所有模塊

getModuleList()

  • 獲得一個按初始化順序的模塊列表

返回一個不可修改的已加載模塊序列晶通,如果沒被初始化則返回 null

public List<IFloodlightModule> getModuleList() {
    if (loadedModuleList == null)
        return Collections.emptyList();
    else
        return Collections.unmodifiableList(loadedModuleList);
}

runModules()

for (IFloodlightModule m : getModuleList()) {
        for (Method method : m.getClass().getDeclaredMethods()) {
            Run runAnnotation = method.getAnnotation(Run.class);
            if (runAnnotation != null) {
                RunMethod runMethod = new RunMethod(m, method);
                if(runAnnotation.mainLoop()) {
                    mainLoopMethods.add(runMethod);
                } else {
                    runMethod.run();
                }
            }
        }
    }

for 循環(huán)遍歷模塊中的方法璃氢,找到@run注解的方法為主方法,以下的就是 FloodlightProvider 提供的 run 方法

@Run(mainLoop=true)
public void run() throws FloodlightModuleException {
    controller.run();
}

運行控制器的模塊

 mainLoopMethods.get(0).run();
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末狮辽,一起剝皮案震驚了整個濱河市一也,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌喉脖,老刑警劉巖椰苟,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異树叽,居然都是意外死亡舆蝴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門题诵,熙熙樓的掌柜王于貴愁眉苦臉地迎上來洁仗,“玉大人,你說我怎么就攤上這事性锭≡剩” “怎么了?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵草冈,是天一觀的道長她奥。 經(jīng)常有香客問我,道長怎棱,這世上最難降的妖魔是什么方淤? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任,我火速辦了婚禮蹄殃,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘你踩。我一直安慰自己诅岩,他們只是感情好讳苦,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著吩谦,像睡著了一般鸳谜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上式廷,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天咐扭,我揣著相機(jī)與錄音,去河邊找鬼滑废。 笑死蝗肪,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蠕趁。 我是一名探鬼主播薛闪,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼俺陋!你這毒婦竟也來了豁延?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤腊状,失蹤者是張志新(化名)和其女友劉穎诱咏,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體缴挖,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡袋狞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了醇疼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片硕并。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖秧荆,靈堂內(nèi)的尸體忽然破棺而出倔毙,到底是詐尸還是另有隱情,我是刑警寧澤乙濒,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布陕赃,位于F島的核電站,受9級特大地震影響颁股,放射性物質(zhì)發(fā)生泄漏么库。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一甘有、第九天 我趴在偏房一處隱蔽的房頂上張望诉儒。 院中可真熱鬧,春花似錦亏掀、人聲如沸忱反。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽温算。三九已至怜校,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間注竿,已是汗流浹背茄茁。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留巩割,地道東北人裙顽。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像喂分,于是被迫代替她去往敵國和親锦庸。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理蒲祈,服務(wù)發(fā)現(xiàn)甘萧,斷路器,智...
    卡卡羅2017閱讀 134,702評論 18 139
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,293評論 25 707
  • 20160924梆掸,21/70扬卷,晚間打卡 今天決定開始拜讀秋葉大神的《如何高效讀懂一本書》——序篇。 大神說要合理搭...
    諸慧的身心園地閱讀 127評論 0 0
  • 兒子要在魔都站穩(wěn)腳跟酸钦,選房買房裝修怪得,我們就開始不斷穿梭在這個城市與故鄉(xiāng)之間。期間有很多故事卑硫,要是細(xì)細(xì)叨叨寫出來徒恋,夠...
    xhy0606閱讀 464評論 2 8
  • 我一直覺得我工作上的好多問題會后知后覺是因為我前提思考并不全面,前瞻性不好欢伏,之前不熟悉都成為我判斷的因素入挣,可當(dāng)這件...
    ee085cf29169閱讀 666評論 0 0