OpenDaylight開(kāi)發(fā)學(xué)習(xí)筆記基礎(chǔ)篇

一 、摘要

本文主要針對(duì)Openflowjava部分進(jìn)行實(shí)例簡(jiǎn)述,初學(xué)者需要對(duì)java了解一些,總結(jié)一些我自己的學(xué)習(xí)收獲,不足之處請(qǐng)指正。

Openflowjava工程作為Opendaylight南向接口的協(xié)議棧存在,與openflowplugin工程及外部的netty.io網(wǎng)絡(luò)庫(kù)緊密聯(lián)系。其主要作用是接受南向接口上報(bào)的消息、解碼、將其交給Openflowplugin以便進(jìn)一步上報(bào)以及接收Openflowplugin傳達(dá)的發(fā)送消息的指令并將其編碼為字節(jié)流從南向接口中發(fā)出。結(jié)構(gòu)上與功能相關(guān)的是Openflow-protocol-api及Openflow-protocol-impl兩個(gè)文件夾下的代碼。 前者中用一系列yang文件定義了控制器支持的Openflow消息結(jié)構(gòu)及對(duì)應(yīng)的收、發(fā)行為,后者包含了消息的解碼、編碼及上報(bào)、下發(fā)的功能邏輯。

netty.io網(wǎng)絡(luò)庫(kù)在Opendaylight中負(fù)責(zé)處理控制器與switch間的TCP連接。控制器接收上報(bào)的Openflow消息時(shí),消息的二進(jìn)制字節(jié)流會(huì)被裝入netty的Bytebuf類對(duì)象中傳遞給Openflowjava來(lái)提供解碼,發(fā)送消息時(shí),消息相關(guān)的數(shù)據(jù)在編碼序列化后被封裝進(jìn)Bytebuf類中交給netty完成發(fā)送。Openflowplugin作為opendaylight處理openflow消息的外掛組件進(jìn)一步負(fù)責(zé)解碼后消息的分類、處理、上傳以及發(fā)送消息時(shí)控制器指令數(shù)據(jù)的分發(fā)、消息體數(shù)據(jù)的組織與打包。Openflowplugin控制著openflow消息收發(fā)的流程和邏輯,openflowjava作為其末端動(dòng)作的執(zhí)行者存在。

二?、Openflow-protocol-api部分開(kāi)發(fā)

openflow-protocol-api文?件?夾?下?的?代?碼?主?要?是openflow-protocol-api/src/main/yang路徑下的一系列yang文件,yang是一種表示結(jié)構(gòu)與屬性的語(yǔ)言,同時(shí)也是一個(gè)RFC標(biāo)準(zhǔn)(RFC6020)?。Opendaylight使用這種語(yǔ)言來(lái)定義其所支持的openflow消息結(jié)構(gòu)以及消息的收發(fā)動(dòng)作。在項(xiàng)目編譯階段,maven會(huì)調(diào)用opendaylight的yangtools工具根據(jù)yang文件生成一系列java文件,包括各openflow消息的容器類、?容器類的構(gòu)造器以及偵聽(tīng)并接收這些容器類的接口。?通過(guò)yang文件,我們可以簡(jiǎn)單清晰地定義我們需要的消息類型以及其上傳/下發(fā)管道。

在上述路徑下最為重要的是openflow-protocol.yang及openflow-types.yang兩個(gè)文件,前者定義了openflow消息和動(dòng)作,后者包含了自定義、非yang語(yǔ)言內(nèi)置的特殊數(shù)據(jù)類型。此目錄下我們主要進(jìn)行yang文件的改寫,將一些協(xié)議的字段寫成yang的形式,主要進(jìn)行openflow-protocol.yang與openflow-types.yang兩個(gè)model中的協(xié)議添加。

在openflow-protocol.yang文件中,grouping語(yǔ)句用于定義一個(gè)數(shù)據(jù)結(jié)構(gòu)塊,uses語(yǔ)句可將其他grouping結(jié)構(gòu)塊復(fù)用進(jìn)當(dāng)前結(jié)構(gòu)塊。通過(guò)這種方法可定義對(duì)應(yīng)于所有openflow消息的數(shù)據(jù)結(jié)構(gòu)塊。但這些結(jié)構(gòu)快并非對(duì)openflow消息中所有字段的映射。如果這是一個(gè)從南向接口接受的消息,則結(jié)構(gòu)快中只需要包含希望從消息獲取并進(jìn)一步上報(bào)的字段。如果是發(fā)送的消息,其結(jié)構(gòu)快中只需要包含那些來(lái)自于控制器指令的數(shù)據(jù)。而length、padding等字段則不需要包括。也就是說(shuō),yang文件中消息的定義是對(duì)實(shí)際的openflow消息中有用數(shù)據(jù)的一種抽象。下面是yang文件中對(duì)flow-stats消息的數(shù)據(jù)結(jié)構(gòu)塊定義。

在定義了消息結(jié)構(gòu)后,還需要在同一yang文件內(nèi)定義消息的行為。相關(guān)的語(yǔ)句是notification和rpc。notification用于定義控制器被動(dòng)等待收取的消息的收取行為。rpc用于定義控制器主動(dòng)發(fā)送的消息的發(fā)送行為以及可能的switch應(yīng)答消息的收取行為。如使用notification定義的hello消息的收取行為是:

其中input語(yǔ)句塊是發(fā)送的定義,output語(yǔ)句塊是收取的定義,uses語(yǔ)句后的是之前定義的對(duì)應(yīng)消息的結(jié)構(gòu)塊。利用上述的yang語(yǔ)法我們就可以定義各個(gè)openflow消息的結(jié)構(gòu)和行為了。在openflow-protocol-api目錄或openflowjava根目錄下用maven完成項(xiàng)目編譯后在openflow-protocol-api/target/generated-sources/sal路徑下可以找到y(tǒng)ang文件生成的消息結(jié)構(gòu)相關(guān)的java文件。他們將會(huì)在編解碼中被用到。Yang和java之間的對(duì)應(yīng)生成關(guān)系詳見(jiàn)opendaylight的如下wiki頁(yè)面。

三?、Openflow-?-?protocol-?-?impl部分

該文件夾下的開(kāi)發(fā)主要針對(duì)消息的編解碼模塊以及上報(bào)/下發(fā)邏輯。先講解碼模塊及邏輯流程。解碼模塊位于路徑Openflow?protocolimpl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization

TypeToClassMapInitializer.java和MessageDeserializerInitializer.java兩個(gè)文件。它們初始化兩張表,前者包含了openflow消息type值到消息類型的映射關(guān)系,?后者包含了消息type值、?消息類型和對(duì)應(yīng)的解碼模塊間的映射關(guān)系。

根據(jù)這兩張表,可以將netty傳遞來(lái)的包含了openflow消息二進(jìn)制字節(jié)流的Bytebuf對(duì)象傳遞給對(duì)應(yīng)消息類型的解碼模塊。如果對(duì)opendaylight的消息有增刪修改的話,?需要相應(yīng)地調(diào)整這兩張表,?同事import語(yǔ)句也需要做相應(yīng)調(diào)整。解碼模塊位于路徑openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/deserialization/factories下,每一個(gè)java文件對(duì)應(yīng)一種消息。文件中的java類繼承OFDeserializer和DeserializerRegistryInjector兩個(gè)類,解碼過(guò)程由其中的deserialize方法實(shí)現(xiàn)。這個(gè)方法接受netty傳來(lái)的一個(gè)Bytebuf類實(shí)例rawmessage作為參數(shù),在內(nèi)部使用yang文件生成的該類型消息的的構(gòu)造器及消息子結(jié)構(gòu)的構(gòu)造器(xxbuilder)以及Bytebuf類的方法進(jìn)行解碼。具體來(lái)說(shuō),使用Bytebuf的一系列read方法線性地將rawmessage中存儲(chǔ)的二進(jìn)制字節(jié)流中的各消息字段讀出來(lái),然后使用消息構(gòu)造器或消息子結(jié)構(gòu)構(gòu)造器的set函數(shù)寫入到消息構(gòu)造器的各實(shí)例域中。每調(diào)用一次rawmessage的read方法,rawmessage中指示讀取位置的一個(gè)游標(biāo)就會(huì)向后移動(dòng)相應(yīng)位數(shù),以便下次調(diào)用時(shí)讀取下一個(gè)字段。讀取和寫入的順序按照消息中字段的順序。?如此將一條消息中所有有用的字段都讀取并賦給消息的構(gòu)造器(xxbuilder)?,最終構(gòu)造器使用自己的build方法返回作為解碼結(jié)果的類實(shí)例。這個(gè)類的定義同樣是由yang文件編譯生成的。Hello消息的示例代碼如下:

解碼的結(jié)果——一個(gè)類實(shí)例將被傳遞給connectionadapter模塊, 該模塊的實(shí)現(xiàn)位于

openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/connection/ConnectionAdapterImpl.java文件中,?其中一系列以Future>為返回值的函數(shù)是yang中使用rpc定義的消息動(dòng)作的收發(fā)實(shí)現(xiàn),而consume方法是notification定義的消息動(dòng)作的實(shí)現(xiàn)。先看consume方法,解碼的結(jié)果——一個(gè)類實(shí)例作為參數(shù)message傳遞進(jìn)來(lái),在方法內(nèi)部使用一系列if語(yǔ)句判斷該message屬于何種消息的類,?一旦匹配則傳遞給messageListener類中相應(yīng)的on方法(這些on方法是根據(jù)yang文件中的notification語(yǔ)句生成的),之后message就被傳遞到openflowplugin中去了。示例如下:

編碼模塊位于路徑openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization下,其中的MessageFactoryInitializer.java用于初始化一張表,表示將要發(fā)送的消息類型與其編碼模塊間的映射關(guān)系。Openflowjava得到openflowplugin傳遞來(lái)的消息類實(shí)例調(diào)用connectionadapterimpl中的那些以Future>為返回值的函數(shù)并通過(guò)這張表找到需要的編碼模塊。實(shí)際的編碼工作在路徑openflow-protocol-impl/src/main/java/org/opendaylight/openflowjava/protocol/impl/serialization/factories下的java文件中展開(kāi)。這些類繼承OFSerializer<>類,其中的serialize方法以openflowplugin傳遞來(lái)的xxinput類實(shí)例message和Bytebuf類實(shí)例outBuffer為參數(shù)。將message中的實(shí)例域提取出來(lái)傳遞給

outBuffer,調(diào)用outBuffer的一系列write方法將其以二進(jìn)制字節(jié)流形式寫入outBuffer中,寫入的順序按照openflow消息的定義,其中也可能包括消息子結(jié)構(gòu)的編碼,類似于解碼中的子結(jié)構(gòu)解碼。除了message中包含的字段外,還需要根據(jù)情況填寫length、padding等字段。填寫完畢后outBuffer由netty完成對(duì)外發(fā)送,編碼的流程就此結(jié)束。至此openflowjava工程中的工作結(jié)束。

四?、?總結(jié)

以上是關(guān)于openflowjava部分的開(kāi)發(fā)文檔簡(jiǎn)述,?具體的消息類型或協(xié)議可以自行進(jìn)行添加和修改,本人知識(shí)水平有限,不足之處還請(qǐng)諒解。

本篇文章由OpenDaylight群(194240432)@北郵-Kobe提供,歡迎共同探討。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,058評(píng)論 25 709
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 34,718評(píng)論 18 399
  • 檢視閱讀是閱讀書籍,主動(dòng)思考的過(guò)程,我們需要清楚下面幾個(gè)問(wèn)題: 1.這本書是講什么的? 2.這本書是怎么寫的? 3...
    小草飛揚(yáng)閱讀 218評(píng)論 0 0
  • 做人,不要瞧不起別人 人活著,誰(shuí)都不用瞧不起誰(shuí)。 三年河?xùn)|,三年河西, 潮起潮又落。 家財(cái)萬(wàn)貫,買不了太陽(yáng)不下山;...
    正能量心語(yǔ)閱讀 555評(píng)論 0 1

友情鏈接更多精彩內(nèi)容