ONOS编程系列(四)Provider开发

在学习本篇文章的时候,笔者假设读者已经读过该系列的前几篇文章,或者对于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:

原文发布于微信公众号 - SDNLAB(SDNLAB)

原文发表时间:2016-04-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏杂烩

一种海量日志存储、分析解决方案V1.1 原

针对上一个版本https://my.oschina.net/shyloveliyi/blog/786337,有如下更新:

12330
来自专栏Java技术栈

让面试官颤抖的 HTTP 2.0 协议面试题

Http协议,对于拥有丰富开发经验的程序员来说简直是信手拈来,家常便饭。虽然天天见,但是对于http协议的问题,可能很多人在没有积极准备的情况下,不一定能很好的...

22620
来自专栏xingoo, 一个梦想做发明家的程序员

【AngularJS】—— 11 指令的交互

前面基本了解了指令的相关内容:   1 如何自定义指令   2 指令的复用 本篇看一下指令之间如何交互。学习内容来自《慕课网 指令3》 背景介绍 ...

20790
来自专栏用户画像

5.3 输入/输出(I/O)管理

首先根据I/O请求中的物理设备名查找系统设备表(SDT),从中找出该设备的DCT,再根据DCT中的设备状态字段,可知该设备是否正忙。若忙,便请求I/O进程的PC...

10130
来自专栏Kevin-ZhangCG

什么是死锁?死锁发生的四个必要条件是什么?如何避免和预防死锁产生?

24950
来自专栏Java帮帮-微信公众号-技术文章全总结

Java并发学习1【面试+工作】

22780
来自专栏Android开发实战

WorkManager _Android新架构组件

5月8号, I/O大会上推出了Architeture新组件WorkManager。 由于Android版本的不断更新,后台任务的处理变得越来越复杂。 因此,Go...

37620
来自专栏SDNLAB

P4语言编程快速开始

经过前两篇的P4理论介绍,相信大家已经对P4有个基本的了解了,本片文章为大家带来P4语言编程实战。 1、系统环境安装 P4项目的官方文档上都是以Ubuntu为例...

48260
来自专栏cloudskyme

分布式文件存储的数据库——Mongodb

什么是mongodb MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。    MongoD...

45460
来自专栏思考的代码世界

Python网络数据采集之使用API|第03天

百度百科关于API的解释:API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序...

54570

扫码关注云+社区

领取腾讯云代金券