一 、 摘要
本文主要在 Helium 版本下进行二次开发测试,涉及到 controller、与openflowplugin&Java、integration 等工程的设计与代码的写入。文章中对于一些概念性问题相信大家已经了解很多,故本文不做过多的解释,只介绍技术。本文目标为以下几点:
- 源代码的下载与编译测试以及启动;
- 三个工程的集成开发,涉及到工程的讲解;
- Controller 里新建 bundle 以及功能解释。
二、源码下载及编译及启动
图1 -版本架构
图1所示是新版本的架构图,只简单介绍几个重要的部分,如北向、功能模块部分与openflowplugin&Java。工程主体由三部分组成,北向负责以上各种网络应用,功能模块部分负责消息的收发以及与上层应用通信,openflowplugin&Java主要负责消息网络流的编解码。下面进入正题。
2.1 Controller编译
mvn命令新建一个folder :
1 2 |
mkdir [name ] cd [name] |
下载源代码:
1 |
git clone http://git.opendaylight.org/gerrit/p/controller.git |
联网编译整个controller工程
1 |
mvn clean install |
编译后报错误并且controller里的一些目录的编译也会skip:
解决办法如下:
现将opendaylight版本切换,我这里是切换到sr2版本相对稳定,
1 |
git checkout release/helium-sr2 |
再下载parent代码
1 |
git clone http://git.opendaylight.org/gerrit/p/odlparent.git |
将odlparent里setting.xml文件copy到你的本地数据库中(.m2)
1 |
cp setting.xml /root/.m2 |
在进行controller的编译就不会报错了。
2.2 Karaf简介与调试
Karafmodule会把Plugin制作成KarafFeature,然后打包成可以导入到Apache karaf的kar文件。
1.Apache Karaf
基于OSGI的运行环境,做为OSGI应用的管理容器提供各种管理utility。
2.KarafFeature
由多个Java运行文件组成的Karaf的功能管理单位。ODL Helium中,所有应用包括MD-SAL都由Apache Karaf统一管理。
编译好controller后,去opendaylight目录下找到distribution,如下图所示:
然后在terminal下cd到bin目录下利用karaf启动controller
1 |
./karaf |
图2 karaf启动controller
启动controller时会发生一些问题,例如:
试着敲入两个命令:
1 2 |
export set JAVA_OPTS=”-Xms256m -Xmx512m” export MAVEN_OPTS="-Xmx1024m -XX:MaxPermSize=512m” |
这两个命令是更改内存的,但是只是临时的更改,这样再启动controller就不错报错,但是需要将两个命令写进etc的profile文件中。
1 |
# gedit /etc/profile |
在最后加入PATH的设置如下:
1 |
export set JAVA_OPTS="-Xmx512m" |
三、controller、openflowPlugin&Java集成开发测试
integration是一个框架性的工程,所有自己开发和修改的部分(包括以上三个工程),编译为包后,都可以放在该工程的目录下一起执行。
注意,如果是自己开发的包,则可以直接放到该目录下。但是如果是修改的原本工程,然后编译的包要替换掉上面目录中原来的包,这里有个问题是 integration 的 plugin目录下的包名和 controller, openflowplugin, openflowjava 中编译出来的包命名方式有点小差别,复制过去之前先重命名下,使之和目录下的原来包文件名一致,再复制替换。
1 |
mvn clean install |
对于helium版本的代码结构变化较大,目录发生了变化,参考一下目录:
1.openflowJava:
1 |
/root/integration/distributions/karaf/target/assembly/system/org/opendaylight/openflowjava/ |
2.openflowPlugin:
1 |
/root/odl_Helium/integration/distributions/karaf/target/assembly/system/org/opendaylight/openflowplugin |
3.controller
对于controller,用于接受openflowplugin上报的消,其实现功能模块是model里包括model-flow-service等。
1 |
/root/odl_Helium/integration/distributions/karaf/target/assembly/system/org/opendaylight/controller/model |
将各个工程的jar包copy到integration里后,运用mvn clean install 编译integration。
四、controller新建一个bundle
控制器功能模块部分,每个模块以一个bundle方式独立开发。开发一个openflowPlugin工程发送OF 数据包 的 bundle。
4.1 Bundle建立
为模块新建一个 支持 OSGi框架的 bundle 。联网 环境下,在命令行终端 开发路径下, 用以下 命令 完成 bundle建立,
1 |
mvn archetype:generate -DgroupId=org.opendaylight.md.controller.Ted -DartifactId=cvniTed -DarchetypeArtifactId=maven-archetype-quickstart -Dpackage=com.org.opendaylight.md.controller.Ted.cvniTed -DinteractiveMode=falsew |
根据Java包名的规范性,一般都是企业的网址倒过来,所以groupId为org.opendaylight.md.controller.Ted,artifactId为你bundle的名字。最后的package是两者加起来。
4.2 框架设计
第一步生成的工程目录下只有一个 app.java文件,删除并 新建 Activator.java文件,并写入一下基础代码:
Activator.java文件用于启动bundle。
4.3 Handler
新建一个Tedhandler.java文件用于收发数据包。本文为收发数据包添加接口,并重写接口里的方法,如下所示:
图3 TedHandler
如图3 所示 TedHandler实现PacketProcessingListener接口,实现接口一定要重写接口里面的方法,如下图所示:
重写了onPacketReceived方法,并在方法的作用域内添加消息的实例,并进行通过各个消息的类引用调用我们在controller的YANG里定义的那些消息字段实现收发包。
4.4 model模块
controller里model模块:
图4 model架构
如图4所示model包含的功能模块,我们要在model-flow-service里面的YANG进行添加协议字段用于匹配openflowplugin,model-inventory也会用到。
编译整个model后会在yang-gen-sal生成对应消息类型的jar包,在刚才说的TedHandler里将生成的依赖包要import进去。然后进入cvniTed目录下编译整个bundle。至此南向协议的代码配置基本完成,然后可以连接一个交换机,用wireshark进行抓包测试。
编译bundle时候可能会碰到这样的问题,如下图所示:
如图中黑色标注所示,这种错误是因为maven进行代码格式的checkstyle,针对这种问题可以选择去pom文件中将checkstyle注释掉。即默认不检查代码格式。Pom路径为如下图所示:
五、控制器功能模块部分
每个模块以一个 bundle 方式独立开发。
5.1 如何开发一个发送 OF 数据包的 bundle
5.1.1 Activator 中添加收发数据包收发接口
新建另一个类 XXHandler.java, 作为该 bundle 的数据包接收发送类。
在 Activator 中数据成员区添加以下代码:
1 2 |
Private XXHandler xxHandler; private Registration xxRegistration; |
在 onSessionInitialized 函数中添加以下代码, 注册一个 XxService 作为 xxHandler 发送数据包服务接口, 这个 setXxService 函数由 XXHandler 类定义, XxService 由 controller 中写的yang 文件对应的 rpc 部分生成, 如下例子中的代码。
1 2 |
xxHandler=new XXHandler(); xxHandler.setPacketPathSetupRequestService(session.getRpcService( PacketPathSetupRequestService.class)); |
在 onSessionInitialized 函数中添加以下代码, 注册 xxHandler 作为整个 bundle 的接收数据包的接口:
1 |
xxRegistration=notificationService.registerNotificationListener( xxHandler); |
5.1.2 在 XXHandler.java 中实现数据包收发的具体操作
定义类 XXHandler 时要通过以下代码继承数据包接收的接口方法(可以有多个),XXListener 由 controller 中写的 yang 文件对应的 notification 部分生成class CvniTedHandler implements XXListener{}函数;
在类中添加函数 onXXreceived(){},重写( override) 继承过来的 onXXreceived 方法, 如下代码。 这个方法内部就是通过 XXReceived 类(由 controller 中写的 yang 文件对应的 notification 部分生成) 对应的 get 函数将数据包每个字段解析出来,加以处理。
1 2 3 |
@Override public void onPacketPathSetupReceived(PacketPathSetupReceived notification){ } |
5.1.3 实现数据包发送功能
可以在上面的 XXHandler 类中,也可以在其他类中(需要把XXHandler 类中的 XxService 赋给另一个类使用),具体发送可以参考下面例子。
builder 由 controller 中写的 yang 文件对应的 rpc 的 input 部分生成。xxService 中生成的接口函数。
1 2 3 4 5 |
PacketPathSetupRequestInputBuilder input = new PacketPathSetupRequestInputBuilder(); input.setxx1(…); input.setxx2(…); … xxService. packetPathSetupRequest(input.build()); |
5.2 不同 bundle 之间的通信
1)在需要被其他 bundle 访问的类(假设叫 Sample) , 再新建一个 SampleService 接口类, 其中要声明需要被其他bundle 调用的函数,如下图:
2)在 sample 类中继承 SampleService 接口类, 并实现( override)在 service 类中声明的函数。
3)在 Activator 中将供其他的 bundle 访问的 SampleService 类注册给 osgi 服务中心。
1.添加以下成员,
2.在该bundle 启动时候注册该 service 到 osgi 服务中心。
在其他 bundle 中 bundle 访问以上步骤其他 bundle 开放的部分, 黄色部分是以上截图中定义的接口函数。 紫色分为固定格式,不需修改,只要放在同一个类下面,直接调用即可。
六、总结
以上就是关于源代码的下载与编译测试以及启动、三个工程的集体开发,涉及到工程的讲解以及Controller里新建bundle的学习笔记。本人知识水平有限,不足之处还请谅解。
本篇文章由OpenDaylight群(194240432)@北邮-Kobe提供,欢迎共同探讨。