天天看點

Opendaylight課堂之深度剖析toaster(一)

寫本篇文章的時候,odl釋出的版本已經是碳版本,下面的mytoaster即采用最新版本。本篇主要參考opendaylight-wiki,這裡吐槽一下odl wiki,在去年wiki更新速度特别差,即使照wiki一步一步敲代碼,也很難能夠把toaster完成。

一、下載下傳源代碼

下載下傳odlparent、controller以及netconf目錄。編譯順序以及簡要說明一下:

1)odlparent是controller的父工程。

2)controller是核心内容。

3)netconf,在某個版本(可能是硼)開始restconf和netconf兩個元件合并了,我們需要restconf。

4)編譯方法

編譯方法就是按照上面順序,執行的指令如下:

mvn clean install -DskipTests -Dskip.karaf.featureTest=true -Dmaven.test.skip=true -Dcheckstyle.skip=true  -Dmaven.javadoc.skip=true

提醒I:對于odlparent、netconf這兩個工程我們可以不用下載下傳,是以odl官方每天都會釋出對應的版本,我們隻需要在controller中pom檔案增加對這兩個工程的依賴就可以了,在編譯controller的時候就會把這兩個工程已經編譯好的版本下載下傳下來了。(此處隻是為了學習才下載下傳)

提醒II:為了能夠順利完成toaster,第一步肯定是要先把代碼編譯通過,編譯過程可能會出現一些錯誤,因人而異(網絡問題),此處不再展示。

提醒III:由于odl官方每天都在建構版本,是以如果一天無法完成demo,可設定maven settings.xml檔案,設定成離線模式,這樣即使第二天在編譯的時候也不會自動更新版本。具體設定如下,增加一個配置項:

<offline>true</offline>

提醒IV:我采用的系統是centos7.0,開發工具IDE:idea-IC。Linux下如何配置maven以及Idea如何建立工程不是本篇内容,請自行百度。

二、工程配置

為了完成這個demo需要增加一些工程配置,所有源碼都會提供。

1、建立工程目錄

 為了和odl官方提供的toaster區分開,demo名字改成mytoaster。我們将根目錄設定在controller/opendaylight/md-sal,工程pom檔案,以odl官方toaster為準,隻需要修改groupId、artifactId以及工程名稱。具體修改如下:

1)在md-sal,目錄中建立一個demo2目錄,并把md-sal/samples/pom.xml拷貝到demo2中。

2)修改pom檔案中groupId、artifactId以及工程名稱。

<groupId>org.opendaylight.controller.demo2</groupId>
  <artifactId>sal-demo2</artifactId>
  <packaging>pom</packaging>
 
  <modules>
    <module>mytoaster</module>
    <module>mytoaster-provider</module>
    <module>mytoaster-consumer</module>
  </modules>
           

2、增加feature

   odl是以feature方式,部署功能子產品,是以需要增加我們自己的feature。修改檔案如下:

三、定義模型--mytoaster

 衆所周知,在odl中開發一個功能一般是如下三步驟:定義模型、實作服務(模型rpc、notification)、使用服務。其中實作服務和使用服務,可以了解成生産者和消費者。

需要要在demo2目錄做:

1、建立目錄: mkdir -p mytoaster/src/main/yang/

2、在mytoaster目錄中增加pom檔案(參考sample中)

<groupId>org.opendaylight.controller.demo2</groupId>
  <version>0.0.1-SNAPSHOT</version>
  <artifactId>mytoaster</artifactId>
  <packaging>bundle</packaging>
           

3、在yang目錄中增加yang檔案(參考sample中)

//mytoaster.yang
module mytoaster {
    yang-version 1;
    namespace
      "http://mytoaster.org/toaster";
 
    prefix toast;
    organization "Netconf Central";
    contact
      "Andy Bierman <[email protected]>";
    description
      "YANG version of the TOASTER-MIB.";
    revision "2017-10-14" {
      description
        "Toaster module in progress.";
    }
    identity mytoast-type {
      description
        "Base for all bread types supported by the toaster.
           New bread types not listed here nay be added in the
           future.";
    }
    identity white-bread {
      base toast:mytoast-type;
      description "White bread.";
    }
    identity wheat-bread {
      base mytoast-type;
      description "Wheat bread.";
    }
    identity wonder-bread {
      base mytoast-type;
      description "Wonder bread.";
    }
    identity frozen-waffle {
      base mytoast-type;
      description "Frozen waffle.";
    }
    identity frozen-bagel {
      base mytoast-type;
      description "Frozen bagel.";
    }
    identity hash-brown {
      base mytoast-type;
      description "Hash browned potatos.";
    }
    typedef MyDisplayString {
      type string {
        length "0 .. 255";
      }
      description
        "YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
      reference
        "RFC 2579, section 2.";
    }
    container mytoaster {
      presence
        "Indicates the toaster service is available";
      description
        "Top-level container for all toaster database objects.";
      leaf toasterManufacturer {
        type MyDisplayString;
        config false;
        mandatory true;
        description
          "The name of the toaster's manufacturer. For instance,
                Microsoft Toaster.";
      }
      leaf toasterModelNumber {
        type MyDisplayString;
        config false;
        mandatory true;
        description
          "The name of the toaster's model. For instance,
               Radiant Automatic.";
      }
      leaf toasterStatus {
        type enumeration {
          enum "idle" {
            value 1;
            description
              "The toaster knob position is up.
                      No toast is being made now.";
          }
          enum "work" {
            value 2;
            description
              "The toaster knob position is down.
                      Toast is being made now.";
          }
        }
        config false;
        mandatory true;
        description
          "This variable indicates the current state of
               the toaster.";
      }
      
      leaf darknessFactor {
        type uint32;
        config true;
        default 1000;
        description
          "The darkness factor. Basically, the number of ms to multiple the doneness value by.";
      }
    }  // container toaster
 
    rpc make-toast {
      description
        "Make some toast.
           The toastDone notification will be sent when
           the toast is finished.
           An 'in-use' error will be returned if toast
           is already being made.
           A 'resource-denied' error will be returned
           if the toaster service is disabled.";
      input {
        leaf toasterDoneness {
          type uint32 {
            range "1 .. 10";
          }
          default '5';
          description
            "This variable controls how well-done is the
                   ensuing toast. It should be on a scale of 1 to 10.
                   Toast made at 10 generally is considered unfit
                   for human consumption; toast made at 1 is warmed
                   lightly.";
        }
 
        leaf toasterToastType {
          type identityref {
            base toast:mytoast-type;
          }
          default 'wheat-bread';
          description
            "This variable informs the toaster of the type of
                   material that is being toasted. The toaster
                   uses this information, combined with
                   toasterDoneness, to compute for how
                   long the material must be toasted to achieve
                   the required doneness.";
        }
      }
      output {
        leaf make-info {
            type string;
        }
      }
    }  // rpc make-toast
 
    rpc cancel-toast {
      description
        "Stop making toast, if any is being made.
           A 'resource-denied' error will be returned
           if the toaster service is disabled.";
    }  // rpc cancel-toast
 
    rpc restock-toaster {
        description
          "Restocks the toaster with the amount of bread specified.";
          
        input {
            leaf amountOfBreadToStock {
                type uint32;
                description
                  "Indicates the amount of bread to re-stock";
            }
        }
    }
    
    notification toasterOutOfBread {
      description
        "Indicates that the toaster has run of out bread.";
    }  // notification toasterOutOfStock
    
    notification toasterRestocked {
      description
        "Indicates that the toaster has run of out bread.";
      leaf amountOfBread {
        type uint32;
        description
          "Indicates the amount of bread that was re-stocked";
      }
    }  // notification toasterOutOfStock
    
  }  // module toaster
           

4、編譯

定義完模型後,需要編譯一下:在mytoaster目錄中進行編譯:

[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 43.220 s
[INFO] Finished at: 2017-10-21T15:42:53+08:00
[INFO] Final Memory: 82M/312M
[INFO] ------------------------------------------------------------------------
[[email protected] mytoaster]#
[[email protected] mytoaster]# mvn clean install -DskipTests -Dskip.karaf.featureTest=true -Dmaven.test.skip=true -Dcheckstyle.skip=true  -Dmaven.javadoc.skip=true
[[email protected] mytoaster]#
           

完成以上内容,算是邁出成功的第一步,後面章節開始實作上面rpc以及notification