OpenDayLight 代码学习研究.docx
《OpenDayLight 代码学习研究.docx》由会员分享,可在线阅读,更多相关《OpenDayLight 代码学习研究.docx(15页珍藏版)》请在冰点文库上搜索。
OpenDayLight代码学习研究
ODL学习
修改记录
版本号
修改人
修改日期
新增/修改内容概要
V0.1
***
2014-07-22
ODL概述、设计原则框架结构
V0.2
***
2014-07-23
服务抽象层部分具体源码分析
V0.3
***
2014-07-24
完善sal-core-api模块源码分析
V0.4
***
2014-07-28
sal.core.spi组件源码分析
sal.connection组件源码分析
1.1ODL概述
Opendaylight是一个以模块化、可插拔、灵活的、基于Java的控制器为核心的开源平台。
从北往南,它首先包括供上层应用和业务逻辑使用的北向开放API,有OSGi和REST两类。
上层应用程序利用这些北向API获得网络智能信息、运行算法处理分析以及组合新的网络策略;其次,它包括控制器平台本身,它是一组可动态组合的模块用于汇集网络信息,比如网络中有哪些元素、其统计信息如何等;最南边是能够支持多种协议的南向接口,如Openflow1.01.3BGP-LS等,这些南向接口可以调用设备上服务抽象层SAL。
1.2ODL架构原则
OpenDaylightController在设计的时候遵循了六个基本的架构原则:
(1)运行时模块化和扩展化(RuntimeModularityandExtensibility):
支持在控制器运行时进行安装、删除和服务的更新。
(2)多协议的南向支持(MultiprotocolSouthbound):
南向支持多种协议。
(3)服务抽象层(ServiceAbstractionLayer):
南向多种协议对上提供统一的北向服务接口。
(4)开放的可扩展北向API(OpenExtensibleNorthboundAPI):
提供可扩展的应API,通过REST或者函数调用方式。
两者提供的功能要一致。
(5)支持多租户、切片(SupportforMultitenancy/Slicing):
允许网络在逻辑上(或物理上)划分成不同的切片或租户。
控制器的部分功能和模块可以管理指定切片。
控制器根据所管理的分片来呈现不同的控制观测面。
(6)一致性聚合(ConsistentClustering):
提供细粒度复制的聚合和确保网络一致性的横向扩展(scale-out)。
1.3框架概述
上图所示,南向通过plugin的方式来支持多种协议,包括OpenFlow1.0、1.3,BGP-LS等。
这些模块被动态挂载到服务抽象层(SAL),SAL为上层提供服务,将来自上层的调用封装为适合底层网络设备的协议格式。
控制器需要获取底层设备功能、可达性等方面的信息,这些信息被存放在拓扑管理器(TopologyManager)中。
其他的组件,包括ARPhandler、HostTracker、DeviceManager和SwitchManager,则为TopologyManager生成拓扑数据。
控制器为应用(App)提供开放的北向API。
支持OSGi框架和双向的REST接口。
OSGi框架提供给与控制器运行在同一地址空间的应用,而RESTAPI则提供给运行在不同地址空间的应用。
所有的逻辑和算法都运行在应用中。
控制自带了GUI,这个GUI使用了跟应用同样的北向API,这些北向API也可以被其他的应用调用。
1.4功能概述
1.4.1服务抽象层
服务抽象层(SAL)是整个控制器模块化设计的核心,向下支持多种南向协议,向上为模块和应用支持一致性的服务。
使用SAL提供的接口,用户无需关心南向协议的具体实现细节,可以更多的关注到模块实现逻辑本身。
1.4.2SAL的演进
SAL已经演进成为了一种基于模型的方法。
框架被用于对网络(属性和设备)建模,并动态地在服务应用之间通过北向API和协议插件提供的南向API进行映射。
下图展示了南向插件如何提供网络模型树的部分。
1.4.3MD-SAL
SAL的设计已经从原先的AD-SAL(API-Driven),逐渐演变到了MD-SAL(Model-Driven),这一决定是在2013.10的第14次TSC会议上讨论的。
采用MD-SAL的好处是让北向和南向的API和数据结构可以不管服务和组件的不同,保持独立。
数据和接口基于YANG标记语言进行描述,它描述XML数据结构、组件功能、定义语义元素和关系,作为一个独立系统来为所有组件建模。
新创建的模块可以采用YANG来进行定义,为希望实现的功能创建静态的API,而无需关心跟SAL进行的具体交互和数据结构实现。
2源码部分
2.1服务抽象层
2.1.1sal-common组件
该组件定义了数据的基本读操作(没有写操作)接口以及全局变量的枚举类型接口。
主要分为三个类:
DataStoreIdentifer、GolobalDataStore、packegeinfo三个接口。
(1)DataStoreIdentifer接口
该类的定义了getIdentifier()和getName()两个方法接口。
作用:
该类的主要作用就是定义一个获取数据存储的获取接口,要注意的是其中并没有定义set方法。
(2)GolobalDataStore类
该类继承了DataStoreIdentifer接口并且是一个枚举的类型:
RuntimeInfo("RuntimeInfo"),Configuration("Configuration");
可以看出GolobalDataStore中存放的信息为RuntimeInfo和Configuration,即存储在运行时的基本信息和相关的组件配置信息。
作用:
存放运行时的基本信息和相关的组件配置信息。
(3)Packegeinfo
其实一个预留类,暂时没有定义任何的方法。
2.1.2sal-core-api组件
org.opendaylight.controller.md.sal.dom.api包
该包中定义了一系列DOM(DocumentObjectModel)即文件对象模型操作如只读操作、只写操作以及读写操作。
只要包含以下几个类:
(1)DOMDataBroker接口
DOMDataBroker即文件对象模型数据代理,其继承了AsyncDataBroker()即异步数据代理和DOMDataChangeListener等。
其中重载了文件对象模型数据代理对于DOMDataTransaction(文件对象模型数据事务)只读操作、只写操作以及读写操作的操作。
createTransactionChain()暂时还没搞清楚其作用。
作用:
定义了一个对DOMDataTransaction的统一接口,其返回的是操作方法而不是具体操作。
(2)DOMDataChangeListener
该类继承了AsyncDataChangeListener,提供DOM数据变更监听。
作用:
DOM数据变更监听器。
(3)DOMDataReadOnlyTransaction
作用:
文件对象模型数据事务只读操作。
(4)DOMDataReadTransaction
作用:
文件对象模型数据事务读操作。
(5)DOMDataReadWriteTransaction
作用:
文件对象模型数据事务读写操作。
(6)DOMDataWriteTransaction
作用:
文件对象模型数据事务写操作。
(7)DOMTransactionChain
作用:
重载了DOM事务链对于DOMData的操作类型,返回的是操作类型而不是具体操作结果。
org.opendaylight.controller.md.sal.dom.api包
该包的结构如下:
可以看出该包中有Broker、Consumer以及Provider三个关键类,所以对于这个包要引用下MD-SAL的架构图
其中,Providers意味着提供NBAPI来让其他组件使用服务。
Consumer意味着组件使用了某个或某些Provider提供的服务。
Broker在不同的Provider和Consumer之间路由RCP、通知和数据更新。
Binding意味着通过YANG模式描述的功能所生成(Generate)的Java接口、类或者约定。
所以Binding-Aware意味着某组件/功能使用了YANG生成的数据或者API,而Binding-independent意味着某组件/功能的数据和API是中立的DOM格式,即没有使用生成绑定。
由MD-SAL框架图可以看出该包中Broker承接Provider和Consumer的数据交互。
下面我们具体分析下这几个类。
(1)Provider接口
当创建一个具体的Provider时,通过调用其中onSessionInitiated(ProviderSessionsession);这个相当于注册其中的ProviderSession,而其来源就是Broker中的ProviderSession接口。
(2)Consumer接口
其接口的内容和Provider接口基本一致。
只是职责不同。
当SAL中的组件需要远程调用另外了一个组件时,其就会申请一个相应的Broker。
其通过Broker找到相应的Provider,并与其建立会话。
(3)Broker接口
其中有两个比较重要的接口:
publicinterfaceConsumerSession()
以及publicinterfaceProviderSessionextendsConsumerSession()
Broker通过管理这两个会话来建立Provider和Consumer连接。
而其通信方式是采用模仿RPC的方式(具体的暂时没有研究)。
(4)AbstractConsumer类
其是一个抽象类,它继承了Consumer这个接口,它控制Consumer会话的开始和结束,以及会话的暂停和唤醒。
具体部分实例如下:
publicfinalvoidstart(BundleContextcontext)throwsException{
…
}//控制会话的开始。
publicBrokeraddingService(ServiceReferencereference){
…
}//增加服务
(5)AbstractProvider类
内容和作用和AbstractConsumer差不多,只是其对象换成Provider。
org.opendaylight.controller.sal.core.api
(1)DataStore接口
●IterablegetStoredConfigurationPaths();
该方法主要用于获取数据存储的位置。
●IterablegetStoredOperationalPaths();
该方法主要用于主要用于获取操作数据的路径。
●booleancontainsConfigurationPath(InstanceIdentifierpath);
该方法主要用于?
●booleancontainsOperationalPath(InstanceIdentifierpath);
看完了其内部定义的方法,DataStore到底有什么作用,在什么地方没到它呢?
可以观察下图:
作用:
DataStore实现SALCoreAPI或者SALCoreSPI,组件可以通过DOMDataBroker对DataStore进行操作。
而具体DOMDataBroker怎么找到对应的DataStore请看下面的DataBrokerService。
(2)DataBrokerService
该接口是个数据代理服务,其和一般的Broker设计原理相似,唯一的区别就是没有定义具体的Consumer。
●publicCompositeNodereadConfigurationData(InstanceIdentifierpath);
该方法是获取DataStore接口中的数据路径在Map>>>中的节点。
●publicCompositeNodereadOperationalData(InstanceIdentifierpath);
该方法是获取DataStore接口中的操作数路径在Map>>>中的节点。
●DataModificationTransactionbeginTransaction();
启动传输链?
(3)DataChangeListener
●onDataChanged(DataChangeEventchange);
该接口主要用于监听数据的变化。
(4)DataModificationTransaction
该接口主要用于数据修改事务
(5)DataProviderService
数据提供者服务。
(6)DataValidator
该接口用于数据验证。
org.opendaylight.controller.sal.core.api.model包
(1)SchemaService
该类是最为基础的核心类,它定义了框架中YANG模块注册和会话的建立以及全局Context。
●voidaddModule(Modulemodule)
增加一个YANG模块。
●voidremoveModule(Modulemodule)
移除一个YANG模块。
●SchemaContextgetSessionContext()
获取会话内容。
●SchemaContextgetGlobalContext()
获取全局Context。
2.1.3sal.core.spi组件
org.opendaylight.controller.sal.core.spi包
(1)BrokerModule
●SetextendsBrokerService>>getProvidedServices();
获取Provider提供的服务。
●SetextendsConsumerFunctionality>>getSupportedConsumerFunctionality();
获取支持的消费者功能。
●TgetServiceForSession(Classservice,
ConsumerSessionsession);
获取消费者服务的会话。
org.opendaylight.controller.*.AsyncDataBroker.DataChangeScope包
(1)DOMStore
DOMDataStore为YANG模型提供事务性的树形存储。
●registerChangeListener
寄存器数据变更监听。
提供的子路径的变化会触发寄存器的的数据更改回调。
什么构成的变化依赖于@scope参数。
●DOMStoreTransactionChaincreateTransactionChain();
创建事务链。
(2)DOMStoreReadTransaction
●ListenableFuture?
>>>read(InstanceIdentifierpath);
DOMDataStore的数据读操作。
(3)DOMStoreReadWriteTransaction
DOMDataStore的数据读写操作。
目前该接口未定义任何方法。
(4)DOMStoreThreePhaseCommitCohort
该接口为DOMDataStore的三阶段提交队列接口。
定义了数据提交的三个阶段。
●ListenableFuturecanCommit();
启动关联交易对数据存储的预提交阶段
●ListenableFuturepreCommit();
启动关联交易对数据存储区中的中止阶段。
●ListenableFuturecommit();
数据提交。
●ListenableFutureabort();
启动对关联交易的有关数据存储提交阶段。
(5)DOMStoreTransaction
该接口为DOMStore事务接口。
●publicObjectgetIdentifier();
唯一标示一个事务。
(6)DOMStoreTransactionChain
该接口为DOM数据存储事务链。
事务链中的事务需要被被提交到队列中,并且每一个事务必须要考虑其在事务链前面的事务的影响。
●publicDOMStoreReadTransactionnewReadOnlyTransaction();
在事务链中创建一个只读的事务,该事务的写操作必须被准备或者取消。
●publicDOMStoreReadWriteTransactionnewReadWriteTransaction();
在事务链中创建一个读写事务
●publicDOMStoreWriteTransactionnewWriteOnlyTransaction();
●在事务链中创建一个只读事务
(7)DOMStoreTransactionFactory
工厂提供的方法来构造只读,可读写,只写记录,其可以被用于在检索和修改所存储的信息。
●DOMStoreReadTransactionnewReadOnlyTransaction();
创建一个只读事务。
●DOMStoreWriteTransactionnewWriteOnlyTransaction();
创建一个只写事务。
●DOMStoreReadWriteTransactionnewReadWriteTransaction();
创建一个读写事务。
(8)DOMStoreWriteTransaction
该接口主要用于DOMStore事务的相关写操作。
2.1.4sal.connection组件
org.opendaylight.controller.sal.connection包
(1)ConnectionConstants
这是一个枚举类型,主要是连接的基本信息,如:
address,port,protocol,username,password。
(2)ConnectionLocality
这也是一个枚举信息,主要定义的信息有:
LOCAL,NOT_LOCAL,NOT_CONNECTED。
其中具体如下:
LOCAL("Thiscontrolleristhe(oroneofthe)masterforagivennode"),
NOT_LOCAL("Thiscontrollerisnotthemasterforagivennode"),
NOT_CONNECTED("Thegivennodeisnotconnectedtoanyofthecontrollersinthecluster");
(3)IConnectionListener
该接口为一个空接口,其用于连接监听。
(4)IConnectionService
接口定义了可用于该操作的功能模块的方法以上SAL用于断开或连接到特定的节点。
●publicNodeconnect(Stringtype,StringconnectionIdentifier,Mapparams);
连接到一个节点与指定的节点类型。
●publicNodeconnect(StringconnectionIdentifier,Mapparams);
发现节点类型,能够与指定的参数节点连接。
●publicStatusdisconnect(Nodenode);
取消连接。
●publicvoidnotifyNodeDisconnectFromMaster(Nodenode);
唤醒连接
(5)IPluginInConnectionService
该接口描述由协议插件来实现的方法
●publicStatusdisconnect(Nodenode);
断开连接到该控制器节点。
●publicNodeconnect(***);
连接到一个节点。
(6)IPluginOutConnectionService
该接口描述由SAL连接服务实现的方法
●publicbooleanisLocal(Nodenode);
测试节点是否本地的一个控制器。
●publicConnectionLocalitygetLocalityStatus(Nodenode);
获取本地节点的状态。