编者按:OpenDaylight基于Maven及OSGi架构的代码修改,及产生日志记录级别和OSGi控制台的追踪,并提供L2switch模块的实例代码修改编译。
一、Maven OSGi定义与开发注意事项
Maven是一个项目管理工具,包含了一个项目对象模型(Project Object Model)、一组标准集合、一个项目生命周期(Project Lifecycle)、一个依赖管理系统(Dependency Management System)、和用来运行定义在生命周期阶段(phase)中插件(plugin)目标(goal)的逻辑。当你使用Maven的时候,你用一个明确定义的项目对象模型来描述项目,然后Maven可以应用横切的逻辑,这些逻辑来自一组共享的(或者自定义的)插件。Maven 有一个生命周期,当你运行mvn install 的时候被调用,告诉Maven 执行一系列有序的步骤,直到到达你指定的生命周期。遍历生命周期中的一个影响是,Maven 运行了许多默认的插件目标,这些目标完成了像编译和创建一个JAR 文件的工作。
OSGi技术是面向Java的动态模型系统。OSGi服务平台向Java提供服务,使Java成为软件集成和软件开发的首选环境,提供允许应用程序使用精炼、可重用和可协作的组件构建的标准化原语,这些组件能够组装进一个应用和部署中。
Maven和OSGI开发的注意事项:
OSGi增加了一个模块化的框架,允许Java模块动态加载。这意味着您可以装载和卸载,启动和停止的应用程序不必中断运行的JVM平台。这似乎符合OpenDaylight的主题,使应用程序和协议来插入框架,以适应不同的使用情况和供应商的策略。
Maven是令人惊奇的,因为它自动产生依赖关系,让你仅仅通过改变版本号更改版本,使得构建过程轻松,提供了一个统一的构建系统,提供高质量的项目信息,提供最佳实践发展的指导方针,允许透明地迁移到新功能,直接从源头控制创建更改日志文件,交叉引用来源邮件列表,依赖关系列表,单元测试报告,包括覆盖范围,保持你的测试的源代码在一个单独的,但是平行的源代码树,使用测试用例命名约定定位和执行测试,有测试用例设置环境和不依赖于定制生成的测试准备。
二、OpenDaylight的源码修改
2.1 基于OpenDaylight的OSGi架构的代码修改
举两个最简单的例子,比如把用户名改为admin1和修改device.web中的JS,有两种办法。
2.1.1 命令行方式
进入usermanager.java将admin改为admin1(详见下图),在usermanager/implementation目录下执行:
1 |
mvn clean install |
或者直接在controller目录下执行:
1 |
mvn clean install -plusermanager implementation |
编译子目录,生成的jar包,复制一下,替换掉原来编译生成的opendaylight/plugins下的对应的jar包,不用再整个编译,直接运行即可(这个就是OSGI的好处,它用每个jar包来隔离功能)。
2.1.2 使用eclipse Maven编译目录
在eclipse下,借助maven可以直接编译单个目录,更新到target目录,直接运行即可,更加简洁高效。
修改用户名admin为admin1:
修改device.web:
编译单独的bundle:
Win7下运行controller:
建议:笔者曾经用JDK1.8编译过一个bundle,发现编译失败,更换JDK1.7即可,为避免不必要的麻烦,建议只用JDK1.7。
2.2 OpenDaylight日志记录级别和OSGi控制台的追踪
如想看到包的所有日志消息,更改日志记录级别arphandler从OSGi控制台追查即可。
1 |
osgisetLogLevelorg.opendaylight.controller.arphandler trace |
接下来验证日志记录级别:
1 2 3 4 5 6 7 8 9 |
osgigetloglevel | greparp Logger org.opendaylight.controller.arphandler at level INFO Logger org.opendaylight.controller.arphandler.internal at unknown level Logger org.opendaylight.controller.arphandler.internal.Activator at unknown level Logger org.opendaylight.controller.arphandler.internal.ArpHandler at unknown level Logger org.opendaylight.controller.arphandler_0 at unknown level Logger org.opendaylight.controller.arphandler_0.4 at unknown level Logger org.opendaylight.controller.arphandler_0.4.0 at unknown level Logger org.opendaylight.controller.arphandler_0.4.0.SNAPSHOT at level TRACE |
日志将出现在OSGi控制台,并在opendaylight.log文件中~/controller/opendaylight/distribution/opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/logs/opendaylight.log
在包中启用日志记录,假设每个模块将保持独立的记录每个类/模块的逻辑分离:
1 2 3 4 5 6 7 8 9 |
//Import Java logging packages import org.slf4j.Logger; import org.slf4j.LoggerFactory; //Class object for your logger would be the bundle name e.xHostTracker private static Logger cnameLogger = LoggerFactory.getLogger(ClassName.class); //Different levels of logging. cnameLogger.info("Throw an informational log"); cnameLogger.error("Throw an error log"); cnameLogger.debug("Throw an debug log"); |
修改代码后,单独的构建opendaylight模块,一旦在一个单独的模块编辑代码,需要重构这个模块使代码生效,这是一种减少重构整个平台的方式。
首先,如果一个项目在运行,使用下面的OSGi控制台停止模块,在这种情况下,以arphandler bundle 为例
1 2 3 4 |
osgiss | greparphandler 35 ACTIVE org.opendaylight.controller.arphandler_0.4.0.SNAPSHOT Stop a bundle: osgi stop 35 |
下一步,重构这个模块,当使用mvn clean install 命令重构项目时,将会删除存在的jar包,并且产生一个新的模块,为了能使新的模块加载到,需要去匹配pom.xml下载模块,使用复制命令把模块添加到指定的加载目录。
1 2 3 4 |
cd ~/controller/opendaylight/arphandler #Build the new bundle jar and create a new one. mvn clean install cp target/arphandler-0.4.0-SNAPSHOT.jar ../distribution/opendaylight/target/distribution.opendaylight-0.1.0-SNAPSHOT-osgipackage/opendaylight/plugins/org.opendaylight.controller.arphandler-0.4.0-SNAPSHOT.jar |
最终,新模块被加载到框架,最酷的是JVM从来没有在这个过程中停下来。
1 2 |
Start a bundle: osgi start 35 |
你也能够从来不停止这个模块,使用upgrade命令
1 2 |
Start a bundle: osgi upgrade 35 |
OSGi将这个包放进路径中,并重新加载它,创建自己的模块。
下面是简单的例子,从开启到结束一个模块:
1 2 3 4 5 6 7 8 9 10 |
A method starting a bundle: public void start(BundleContext context) { A method to stop the bundle: public void stop(BundleContext context) { An array is run to get all of the class objects inside of OpenDaylight. Just copy and paste the bundle: public Object[] getImplementations() { Object[] res = { NewClass.class }; return res; } |
Pom.xml是Maven中的一个主要的部分,能够将所有的项目绑在一起,每一个项目有一个pom.xml,并且在这全部的平台有一个超级pom.xml。格式是XML并且完全容易察觉到什么在进行中。
三、l2_switch为模块添实例
将opendaylight中的simpleforwarding替换为md-sal模式l2_forwarding。
停止simpleforwarding模块:
停止后mininet和OSGI的显示:
1 2 3 |
cd SDNHub_Opendaylight_Tutorial-master $cd distribution/opendaylight-osgi-mdsal/target/distribution-osgi-mdsal-1.1.0-SNAPSHOT-osgipackage/opendaylight $ ./run.sh 在控制台可以看见L2_forwarding已经启用 |
启用l2_forwarding后的ping:
发现time都小于1ms,这是因为采用md-sal模式的时候,learning switch追踪主机的mac地址,从而发送数据包到目的地址,而不是像hub一样泛洪处理。如果用hub方式的话,time会大于1ms。
作者简介:
王如迅(OpenDaylight[194240432]@空灵恬静)
北京邮电大学网络技术研究院,网络与交换技术国家重点实验室硕士研究生。