前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ONOS编程系列(四)Provider开发

ONOS编程系列(四)Provider开发

作者头像
SDNLAB
发布2018-04-02 14:53:38
9500
发布2018-04-02 14:53:38
举报
文章被收录于专栏:SDNLABSDNLAB

在学习本篇文章的时候,笔者假设读者已经读过该系列的前几篇文章,或者对于ONOS整个项目的架构有一定的了解,并且电脑上已经有onos-1.1的源程序,能熟练使用ONOS程序。

好了,言归正传。前面几篇有关于应用的,命令的,服务的开发,根据下图ONOS的整体架构描述,这些功能模块都在偏上的层次中,而Provider则处于核心层和协议层之间,是负责与底层设备直接进行交互的部分。这部分,正式能够对OF这些协议做二次开发的关键部分。

本篇文章教程会在测试用的null provider基础之上,创建一个新provider,该provider相较于null provider,会生成LinkDescriptions,与ONOS的核心层进行通信测试。NullLinkProvider没有实现的关键功能,则通过引用OpenFlowDeviceProvider进行实现。

通过本教程,你将会学习到:

Provider的整体架构

如何创建并加载Provider

一、项目骨架

1.1 设置项目目录

首先,为新Provider创建骨架,该项目在${ONOS_ROOT}/providers/目录下,整体骨架如下:

我想在这里有必要介绍一下${ONOS_ROOT}/providers/目录的结构,其深度为2的目录树为:

从上图可以看到,在null根目录下的pom文件的打包格式为pom,说明这个文件夹仅仅是做聚合用的,其他与null平级的文件夹如host,lldp,openflow,其根目录的pom文件打包格式都是bundle。进一步发现,null文件夹下每一个文件夹如device,flow等,其根目录的pom文件打包格式都为bundle。因此可以得到一个结论:

null下面的每个文件夹都是独立的provider,与null平级的其他文件夹也都是独立的provider。不过null在实际运行中没有使用,可能只是做测试用。这个从名字可以猜测而得出。

1.2 添加,编辑POM文件

在null/link/目录下,新建文件pom.xml,该文件用来描述项目信息:

要时刻注意版本号不要搞错,请根据自己的onos的版本号决定内应该写什么版本。

如前所述,null/pom.xml是对null文件夹下的各个provider项目做聚合用的,所以建立link项目根目录以后,要相应在null/pom.xml文件中添加一些声明link模块的语句:

在maven中,项目的聚合是可以层层叠加的,这也是整个onos项目构建的基础之一。在null级别聚合几个providers以后,与null平级的多个providers如何聚合在一起呢?我们查看一下providers/根目录下的pom.xml文件,从中找到了类似的聚合语句,并在其中添加null相关语句(如果没有的话):

1.3 在karaf中注册

在pom文件的聚合下,多个providers组成一组,统一加载,对外表现出一个而不是多个feature。从以上描述中,我们有理由这样安排,将providers/null/文件夹下的所有providers整合成一个feature,统一在karaf中注册。具体怎么做呢?在${ONOS_ROOT}/目录下,有一个名为features的目录,该目录就是karaf识别onos多个模块的关键。

我们需要在${ONOS_ROOT}/features/features.xml文件中添加关于onos-null feature的语句(如果该语句尚未被包含在文件里):

其中蓝框框住的部分是重点,蓝框中的蓝框是重点中的重点。

二、实现Provider功能

2.1 加入必备内容

和前面ONOS编程系列(三)应用模板的代码框架一样,都要使用@Component,@Reference等Felix的SCR注解(注解的解释详情请见http://felix.apache.org/documentation/subprojects/apache-felix-maven-scr-plugin/scr-annotations.html或者翻看该系列前几篇),需要提供日志输出功能,需要做启动前准备activate()和注销后资源回收deactivate()。见下图:

2.2 在服务中注册

我们的Provider是属于Link子系统的一部分,不过还需要其他两个子系统提供帮助:Device子系统负责提供可用设备的信息,Mastership子系统负责提供设备与控制器之间的角色映射。

其中红框框住的部分都是新增的代码,其具体作用见注释。注意,“LinkProvider”应该改为“linkProvider”,要符合驼峰式命名方法,才能通过checkstyle。

该段代码中InternalLinkProvider类属于内部类。在ONOS的命名提议中,凡是内部类,比如Listener,handler,以及导出的service等的命名都应以“Internal”作为其前缀,以表示其为私有内部类。

该内部类的初步实现如下:

2.3 实现与核心层的交互

现在,本Provider有一个providerService可以与核心层进行交互,有一个linkProvider可以获知能够通过链路相互通信的设备信息。Provider作为底层设备与核心层之间的中介的作用从中得以体现。

在继承了DeviceService接口的私有内部类InernalLinkProvider,有且仅有一个必须要覆写的方法event()。我们要在该方法中实现的简单功能就是将网络中实际新增加的连接,这一信息以合适的形式提交给北向核心层。

在覆写event()方法之前,需要定义一些新成员变量:

下面是对event()方法的具体实现:

在对事件进行处理的时候,方法addLink和方法removeLink的实现如下:

现在对于上述提到的两个概念进行简要说明:

1)LinkDescription - 是Provider已经发现的网络连接的集合。我们实现的这个Provider实现的是对于新加入的设备伪造其与前一设备的连接,并不能真实反映网络状况,而真正可用的provider应该能够直接与网络交互,从而上报真实的信息。比如说,LLDPLinkProvider对于每一个已知的设备都维持着一个LinkDiscovery对象。LinkDiscovery会通过其对PacketService的引用向网络发送LLDP包或者从网络收取LLDP包。

2)Mastership - 在该文件中中,该服务用来获取本ONOS实例对于指定id设备的角色。

2.4 增加LinkDriver

在前面的工作中,我们已经实现了建立伪造拓扑的功能。在对ONOS的核心层做压力测试的时候,我们需要该Provider能够提供稳定的LinkDescription的输出。为了实现稳定输出的功能,我们在NullLinkProvider这个类中又加入了LinkDriver类,该类能够在线程没有挂掉的前提下,发送之前已经创建的LinkDescription给核心层。

在此之前,先在文件中import一个外部的函数:

其次,在该类中加入一些必须的成员变量:

然后,将LinkDriver类的实例对象添加到文件中,并使其参与整个activate到deactivate的流程中去:

整个调用框架都写好以后,我们就要实现私有内部类LinkDriver(严格来说,没有“Internal”做前缀的私有内部类是不对滴):

2.5 编译这个Provider

由于该provider涉及的修改仅限于providers/目录,所以在其目录下进行重编译即可:cd ${ONOS_ROOT}/providers &&mvn clean install

如果编译成功,我们就可以开始测试这个provider。

该provider的启动分为动态启动和静态启动,在本系列(一)中有所描述。我们使用动态启动:

然后查看onos-null-*的provider:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2016-04-27,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 SDNLAB 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档