码农学ODL之Toaster代码解析

Toaster(烤面包机)是OpenDaylight的一个例子,该例子的目的不是让你如何烤面包,而是借这个例子学习OpenDaylight的特性。在Toaster中,真正有关烤面包机相关的代码较少,它只是一种OpenDaylight具体思想的展示品,很多情况没有进行考虑。本文将通过烤面包机这个实例来初步探讨OpenDaylight技术的基本思想。

1.Toaster的需求规格

首先,我们来看下烤面包机要实现的需求是什么,从面向对象的角度来考虑,烤面包机做为一个物理实体,它具有生产厂商、型号和面包机状态等相关属性;同时,它也表现出烤面包、取消烤面包、面包机重置等行为,并且当面包机检测到某种情况时,也会发出通知。其详细信息如下:

2.基本实现

面对烤面包机的需求,我们先尝试着去设计一个小熊牌的烤面包机,Toaster类定义烤面包机的属性,可以使用POJO(Plain Old Java Object)定义方式;ToasterService定义烤面包机的行为;BearToaster为小熊烤面包机的具体实现,当其检测到无面包可烤的情况时,会通知Human子类Boy or Girl,client在调用代码构建BearToaster和Human子类对象,其类关系图如下所示:

上图只是简单地设计,考虑到可扩展性、可维护性等因素,至少还需要进一步考虑:如何构造烤面包机对象、如何进行事件的通知以及服务依赖关系如何设置等问题。带着这些问题,我们看下OpenDaylight中是如何实现的?

3.ODL实现

3.1.Yang基础

Yang是一种专门针对NETCONF而设计的建模语言,使用树形结构描述数据,具有良好的可读性,具有数据描述和接口描述两种功能。其基本信息如下所示:

更详细的Yang信息,请参考https://www.sdnlab.com/resource/12292.html
在OpenDaylight中,Yang也被用作一个通用建模语言。Yang文件有两种格式,一种是来定义数据和接口,另一种是定义依赖注入、启动配置等信息。在Toaster实例中,这两种格式的文件分别体现为toaster.yang和toaster-provider-impl.yang。

3.2.Toaster数据模型

3.2.1.Yang数据模型定义
Toaster的Yang建模文件toaster.yang位于toaster/api/src/main/yang/目录下,用于表示Toaster的对外接口以及数据结构,其内容框架如下图所示:

3.2.2.Yang模型代码生成
Yang文件定义好后,我们可以使用Yang Tools进行Yang语法解析、语义模型以及Java文件的映射,这样做可以极大地提高了编程效率。下面我们来分析下Yang 与Java文件之间的映射关系,toaster.yang生成的代码文件如下所示:

首先,来看下包路径的映射关系,toaster.yang文件中定义信息如下:

所以,从定义来看,包路径的映射关系如下:

其次,用来描述数据的Container标识映射到ToasterData.java;用来定义RPC方法的RPC标识映射为ToasterService.java;用来描述异步通知方法的notification标识映射为ToasterListener.java。它们的映射关系如下图所示:

RPC操作和Notification异步通知各自对应接口文件,文件内包含对应相应的方法,如ToasterService文件定义如下,比较简单。

再次,我们来详细说明如何来构造烤面包机的数据?Yang Tools根据Container生成类或接口文件ToasterData、Toaster和ToasterBuilder,其中ToasterData、Toaster是接口类,而ToasterBuilder为具体实例的建造者。其类关系图如下所示:

通俗一点来解释,客户小A想要一台烤面包机(小熊牌、型号R7等),便找ToasterBuilder,让其帮忙构建一台烤面包机,此时ToasterBuilder为难了,因为其只能构建一些零件,不掌握整装技术,怎么办呢?找整装设计师吧,于是ToasterImpl产生了,告诉ToasterBuilder如何一步一步去完成,ToasterBuilder和ToasterImpl相互配合就构建出了小A的烤面包机。

最后,通过上面的分析,我们可以更详细地得到Yang Tools将Yang文件映射为Java文件的关系图,如下所示:

3.3.Toaster的代码实现

从Toaster.yang模型生成的代码可以看出,当前已经定义如何构建Toaster数据以及相关的操作接口,下面我们来看下如何实现一个烤面包机? 在OpenDaylight中,定义了一个品牌为OpenDaylight的烤面包机,它实现了ToasterService、DataChangeListener、AutoCloseable等接口,类关系图大致如下所示:

其中,OpenDaylightToaster类本身定义如下:

在这里,我们主要关注buildToaster、makeToast和onDataChanged三个方法。
1.Toaster的构建方法buildToaster
buildToaster的实现是基于Yang Tools生成的Java类,如下所示:

2. 烤面包makeToast
首先我们来看下,makeToast方法的基本实现逻辑,如下图所示:

首先,读取烤面包机的状态。在OpenDaylight中,所有数据都保存在DataStore中,并且数据以树形结构存储,而DataBroker是访问MD-SAL数据存储的接口,它提供了3种访问方式只读、只写和读写,分别对应newReadOnlyTransaction、newWriteOnlyTransaction和newReadWriteTransaction,具体代码如下所示:

其中TOASTER_IID定义为InstanceIdentifier类型,作为Toaster的实例标识符,表示Toaster在Yang数据树中的位置的唯一标识符,Futures.transform方法返回一个新的ListenableFuture,该值是在参数readFuture 的基础上进行asynFunc 处理后产生的结果。
其次,修改Toaster为工作状态。tx.put方法第一个参数为OPERATIONAL,代表DataStore中存储的数据类型;第三个参数为设置Toaster工作状态为down,具体代码如下:

再次,从状态判断到烤面包或者重试或者报错的过程,使用异步调用的方式,形如:

最后,Task任务进行面包的烘烤,烤面包的代码仅仅进行sleep一段时间。如果遇到outOfBread时,则会发送相应的通知。具体代码如下:

3.onDataChanged通知方法
Toaster中所有的数据都存储在DataStore,当DataStore中的数据发生变化时会通过DataChangeListener触发事件通知,事件通知需要做的事情放在onDataChange方法中实现。具体代码逻辑比较简单,首先获取数据对象,如果该数据对象是Toaster,那么进行一些简单的赋值操作,具体实现如下:

3.4.Toaster服务的Yang配置

到目前为止,已经对烤面包机的数据及接口进行了定义,并实现了品牌为OpenDaylight的烤面包机。这样,如何通过调用接口就能访问OpenDaylight烤面包机的方法,进一步说,我们知道OpenDaylightToaster是基于MD-SAL实现的,那如何使得OpenDaylightToaster与MD-SAL关联起来呢?我们知道,几乎所有的应用程序都必须读取一些配置信息,这些信息通常是通过配置文件来完成的,比如XML或properties文件。对于像OpenDaylight运行于OSGI平台上的应用程序,依赖于哪些包或者服务,以及这些依赖是必须的还是可选的,这些信息都是非常关键的。

这涉及到Config Subsystem,它通过YANG模型来表达Module(模块)配置、依赖和状态数据,具体来说就是通过yang schema来定义配置信息,具体依赖值由config.xml提供,在Toaster实例中toaster-provider-impl.yang和03-toaster-sample.xml。

首先,我们来看下toaster-provider-impl.yang文件的定义,通过import引入依赖模块;通过identity指定Toaster模块标识;通过augment增加类型为toaster-provider-impl的可选节点。

上述Yang文件映射为Java类,需要关注ToasterProviderModule和ToasterProviderModuleFactory,前者的createInstance方法可用来实现OpendaylightToaster实例,后者被MD-SAL调用 ,实例化ToasterProviderModule。下图列出createInstance方法的实现细节,红色部分进行OpenDaylightToaster实例的构建及其对依赖的获取。

其次,我们再来看下03-toaster-sample.xml文件,具体内容如下:

之间,定义toaster-provider-impl模块和它所需的依赖配置(toaster-provider-impl.yang)。
至此,有关一个原始的OpenDaylightToaster就可以了,当然了,真正测试时,你还需要修改feature.xml和pom.xml,然后进行编译、打包。

作者:SDNLAB--SDN/NFV开发团队
简介:致力于SDN/NFV等前沿技术的研究、应用与实践,已研发推出UMS网络流量监控、SDN智能流量调度、NFV管理编排等产品。专注为高校、企业、政府以及电信运营商等客户提供定制化及个性化的SDN/NFV系统开发服务。


  • 本站原创文章仅代表作者观点,不代表SDNLAB立场。所有原创内容版权均属SDNLAB,欢迎大家转发分享。但未经授权,严禁任何媒体(平面媒体、网络媒体、自媒体等)以及微信公众号复制、转载、摘编或以其他方式进行使用,转载须注明来自 SDNLAB并附上本文链接。 本站中所有编译类文章仅用于学习和交流目的,编译工作遵照 CC 协议,如果有侵犯到您权益的地方,请及时联系我们。
  • 本文链接https://www.sdnlab.com/17854.html
分享到:
相关文章
条评论

登录后才可以评论

SDNLAB君 发表于16-09-23
3