searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

ODL模板工程创建、编译、改写和加载

2023-01-17 05:52:01
75
0

【工程模板背景】:

ODL引入了工程模板,用于自动生成对应版本的空工程文件,便于启动新的项目。工程模板生成的项目包含了ODL的基本运行机制,为开发者提供了基础项目框架。

工程模板一般被称做opendaylight-startup,原来是内嵌于controller项目内的子模块,当前已经独立出来成为新的工程,可以在git上搜索opendaylight/archetypes

 

【1.使用模板进行开发的步骤】:

1.下载模板源代码;

2.编译源代码并安装到MAVEN本地仓库,相当于把工程模板或者更形象的叫做工程工厂安装到本地,后续想要生成新的项目模板,只要用工厂去生成就行了;

3.使用安装到本地的工程模板生成新工程;

4.在新工程上做扩展开发;

5.编译、安装、测试新工程;

 

【2.编译工程模板源代码并安装】:

下好工程模板源代码后,使用mvn clean install进行编译和安装。

遇到的坑:

(1)test步骤失败,因为考虑是工程模板,没有必要做测试,所以mvn clean install -DskipTests跳过;

(2)很多文件是windows格式,即换行按CR\LF切换,导致编译失败,使用notepad++中的“编辑” -> “文件格式转换”转成unix格式即可;

(3)会下载很多依赖文件到本地MAVEN仓库,由于网速问题,一个是慢,另一个可能中途断线导致失败,需要多次尝试。另外,也试用了网上的方法,将中央仓库地址配置为阿里云MAVEN仓库镜像地址,下载确实很快,但是出现了一堆乱七八糟的问题,比如某个库版本不匹配,某个库找不到,怀疑是阿里云仓库跟真正的中央仓库还是没有完全同步,所以放弃了阿里云。好在下载的每个小包都不算大,最大的就68M,尝试几次就OK了。

 

【3.使用工程模板生成新工程】:

使用命令:mvn archetype:generate -B -DarchetypeGroupId=org.opendaylight.archetypes -DarchetypeArtifactId=opendaylight-startup-archetype -DarchetypeVersion=1.3.0-SNAPSHOT -DgroupId=sdnlab -DartifactId=helloworld -DclassPrefix=HelloWorld -Dcopyright=sdnlab -DcopyrightYear=2020

命令解析:DarchetypeGroupId、DarchetypeArtifactId、DarchetypeVersion三项是工程模板的信息,这三个信息作为三元组可以唯一的确定一个bundle的坐标。在此处则是根据此三元组确定的bundle(工程模板)生成新的工程。这三个信息可以在工程模板项目的opendaylight-startup中的pom.xml中找到。如下图所示:

剩下的参数是生成的新项目的三元组和描述信息,结合上文比较容易理解,不再赘述。注意没有给新生成的项目指定version,会自动生成一个version。

执行命令后会生成新工程。遇到的坑:

(1)注意生成此命令需要新建一个空文件,在空文件中执行此命令,否则会报错;

(2)遇到了[ERROR] Failed to execute goal pl.project13.maven:git-commit-id-plugin:3.0.1:revision (get-git-infos) on project odl-helloworld: Could not complete Mojo execution...: Error: Could not get HEAD Ref, are you sure you have some commits in the dotGitDirectory? -> [Help 1]一个错误。经过查询资料,发现是pom引用了git-commit-id-plugin插件,此插件的作用是对git的不同版本做出标记,但当前helloword工程是生成的模板工程,所以自然没有.git文件,所以会报错。很奇怪的是,经过查询插件的pom语法,可以通过skip跳过此插件执行,或者可以通过failOnNoGitDirectory设置为false来跳过没有.git的文件,但无论如何设置,都不起效果。我也尝试在工程的pom文件中寻找使用此插件的位置,想通过直接删除掉对此插件的依赖来解决问题,但无论如何也没有搜到哪里使用,估计是跟父工程继承的属性有关系,父工程还没有仔细研究,待后面再看吧。当前实际解决问题的方法是在有需要的目录中增加了git文件,具体通过以下命令:

Solution:

Run in the project directory: git init && git add . && git commit -m 'initial commit'

If an error occurs, run: git config --global user.email 邮箱地址

And then, re-run mvn

是参考了老外的文章:https://nimli-computer.blogspot.com/2019/10/?m=0

需要科学上网才可以看。总结此问题,解决有三个方向:第一,修改此插件,使其能正常跳过没有git的文件;第二,修改工程pom,使工程去掉对此插件的依赖;第三,在需要.git的目录下建立合适的.git。由于第一,第二方法没有搞通,所以选择了第三种方法,其实第三种不是最佳方式,但至少可以解决编译不过的问题。让我们快速把精力投放在更有用的地方。

今天继续review了此问题,上文中第一种方法难度较大,也不是最佳解,本次直接尝试在第二种方法上做突破。排查helloword项目文件中每个子模块的pom文件,发现他们各自继承的父pom都不一样,所以修改父pom不太方便,从继承的角度看也不太合理。所以在每个项目中通过mvn help:effective-pom查看当前继承和聚合后的pom文件样式,从中找到git-commit-id-plugin对应的配置,我们的期望是去掉此plugin,因为无法在父pom中删除此插件依赖,所以只能在子项目中跳过此插件的执行,好在查看此插件的文档发现,可以在configure中通过<skip>true</skip>对其进行跳过处理。方法已经找到,则将通过mvn help:effective-pom查询到的pom文件中,将git-commit-id-plugin相关的内容拷贝出来,并在其中加上skip跳过,并把修改好的这段代码加入工程的pom文件中,注意对于此项目,plugin包含在plugins中,plugins包含在build中。再次编译就可以通过了!

(3)很多文件是windows格式,即换行按CR\LF切换,导致编译失败,使用notepad++中的“编辑” -> “文件格式转换”转成unix格式即可;

(4)会下载很多依赖文件到本地MAVEN仓库,由于网速问题,一个是慢,另一个可能中途断线导致失败,需要多次尝试。另外,也试用了网上的方法,将中央仓库地址配置为阿里云MAVEN仓库镜像地址,下载确实很快,但是出现了一堆乱七八糟的问题,比如某个库版本不匹配,某个库找不到,怀疑是阿里云仓库跟真正的中央仓库还是没有完全同步,所以放弃了阿里云。好在下载的每个小包都不算大,最大的就68M,尝试几次就OK了。

 

【4.在新工程上做扩展开发】:

用IDEA打开新生成的工程,根据需求不同,这里开发的方式也就千差万别了。我本次尝试的比较简单,只改了cli命令。cli目录下sdnlab下的cli下有三个目录分别是api, commands和impl。其中api目录下定义的是一个接口,impl目录下内容是对api中接口的实现类,在此将接口中的方法做了改动,返回hello world!,commands中的类是真正接收和处理用户敲命令行的响应类。它的默认命令行为test-command,还带个-tA的参数。

综上,我只改了impl下的实现方法,返回hello world!而已。

 

【5.编译、安装、测试】:

通过mvn clean install -DskipTests编译安装并跳过测试。编译时间较长,错误较多。编译时间长一方面是因为错误多,每次修改后都需要重编译,且下载的内容多,很占时间。错误主要是windows文件格式和unix文件格式转换问题,还有引用包的顺序问题。模板默认生成的引用顺序不对,错误提示很到位,很容易定位和修改。总之编译和安装没有遇到太难解决的问题,就是耗时间。

测试遇到了难点,我原以为的测试,是跟C语言编程差不多,编写一个模块后,将模块替换到环境上,环境重新启动加载新编译的模块后进行调试。但这个思路我在ODL上没有实现,不知道应该如何提取编译后的“模块文件”,或者更准确的叫做feature文件。我原以为在helloword工程目录下的karaf\target\assembly\system中将sdnlab文件夹整体拷贝到环境上odl的system下,重启后通过feature:install就可以,但重启后找不到helloworld的feature,所以也没法安装。

后来在helloworld工程目录下karaf\target中找到了tar包,看了下大小跟opendaylight大小差不多。放到环境上解压运行后,可以安装helloword的feature!敲命令test-command -tA 123可以返回hello world!



【6.在官方odl的release版本中加入自编译feature】:

由于项目需要,今天研究了上次没有搞定的事情,即如何将自编译的feature如c语言生成的模块一样加入到官方原始安装包中。

首先需要将自己写的odl工程编译通过,然后在项目目录下的helloworld/karaf/target/assembly/system中进行查找(我已经把工作系统从win迁移到mac os了,所以我的实际目录是/Users/lyd/WorkSpace/JavaWorkSpace/opendaylight/helloworld/karaf/target/assembly/system,其中helloworld是我工程所在目录,karaf是编译成功后生成的目录),

可以看到sdnlab文件夹,在进入sdnlab文件夹查看,生成的文件全在这里:

将sdnlab文件夹拷贝到官方release版本的system目录下,即把我们自编译的feature(模块)放在了官方版本的目录下。然后启动odl,通过命令:

feature:repo-add mvn:sdnlab/features-helloworld/0.1.0-SNAPSHOT/xml/features

将自编译feature(模块)读取到版本中,注意这一步是读取,不是加载,目的是让odl知道还有我们这样一个模块。此步骤命令中,黑色字体为固定命令,无需修改,红色字体需要按照自己的项目进行修改,其中sdnlab对应的是文件夹名字,真实项目中常用com.xxx.xxx,所以生成的文件夹也是com.xxx.xxx,features-helloworld是生成的文件夹下的features名字,仅此一个feature,0.0.1-SNAPSHOT是features-helloworld目录下的文件夹名称,代表了版本,以上就是红色字体的来源。然后在odl上通过命令:

feature:install features-helloworld

对feature进行安装,如果不报错就是安装成功,可以测试cli命令行。可以成功执行:

【7.在官方odl的release版本中设置自编译feature自启动】:

步骤6是步骤7的前提,当执行完步骤6后,进入odl下的etc文件夹,编辑org.apache.karaf.features.cfg文件,在featuresBoot后面加上自编译feature名称,如下图所示:

然后再在odl的etc目录下的查找与org.apache.karaf.features.cfg中featuresRepositories =后面的一串数字相同的xml文件,如下图:

vi进去,如下图添加自编译feature两项配置(注意此图圈注有误!!!上面那个圈应该是第6行,不是第7行,第7行是默认就有的,不能改!!!)

修改后保存,启动odl,查询自编译feature,已经成功自动启动:

再查看在自编译feature代码中,默认启动会执行的init函数中打印的日志是否成功打印:

日志在odl的data/log目录下:

在日志中查找打印信息,可以成功找到:

说明自动启动时会执行init函数,我们可以在init函数中做一些我们希望初始化的事情。

 

参考信息:

https://www.sdnlab.com/19931.html

https://blog.csdn.net/Kangyucheng/article/details/91393302

0条评论
0 / 1000
刘****东
2文章数
0粉丝数
刘****东
2 文章 | 0 粉丝
刘****东
2文章数
0粉丝数
刘****东
2 文章 | 0 粉丝
原创

ODL模板工程创建、编译、改写和加载

2023-01-17 05:52:01
75
0

【工程模板背景】:

ODL引入了工程模板,用于自动生成对应版本的空工程文件,便于启动新的项目。工程模板生成的项目包含了ODL的基本运行机制,为开发者提供了基础项目框架。

工程模板一般被称做opendaylight-startup,原来是内嵌于controller项目内的子模块,当前已经独立出来成为新的工程,可以在git上搜索opendaylight/archetypes

 

【1.使用模板进行开发的步骤】:

1.下载模板源代码;

2.编译源代码并安装到MAVEN本地仓库,相当于把工程模板或者更形象的叫做工程工厂安装到本地,后续想要生成新的项目模板,只要用工厂去生成就行了;

3.使用安装到本地的工程模板生成新工程;

4.在新工程上做扩展开发;

5.编译、安装、测试新工程;

 

【2.编译工程模板源代码并安装】:

下好工程模板源代码后,使用mvn clean install进行编译和安装。

遇到的坑:

(1)test步骤失败,因为考虑是工程模板,没有必要做测试,所以mvn clean install -DskipTests跳过;

(2)很多文件是windows格式,即换行按CR\LF切换,导致编译失败,使用notepad++中的“编辑” -> “文件格式转换”转成unix格式即可;

(3)会下载很多依赖文件到本地MAVEN仓库,由于网速问题,一个是慢,另一个可能中途断线导致失败,需要多次尝试。另外,也试用了网上的方法,将中央仓库地址配置为阿里云MAVEN仓库镜像地址,下载确实很快,但是出现了一堆乱七八糟的问题,比如某个库版本不匹配,某个库找不到,怀疑是阿里云仓库跟真正的中央仓库还是没有完全同步,所以放弃了阿里云。好在下载的每个小包都不算大,最大的就68M,尝试几次就OK了。

 

【3.使用工程模板生成新工程】:

使用命令:mvn archetype:generate -B -DarchetypeGroupId=org.opendaylight.archetypes -DarchetypeArtifactId=opendaylight-startup-archetype -DarchetypeVersion=1.3.0-SNAPSHOT -DgroupId=sdnlab -DartifactId=helloworld -DclassPrefix=HelloWorld -Dcopyright=sdnlab -DcopyrightYear=2020

命令解析:DarchetypeGroupId、DarchetypeArtifactId、DarchetypeVersion三项是工程模板的信息,这三个信息作为三元组可以唯一的确定一个bundle的坐标。在此处则是根据此三元组确定的bundle(工程模板)生成新的工程。这三个信息可以在工程模板项目的opendaylight-startup中的pom.xml中找到。如下图所示:

剩下的参数是生成的新项目的三元组和描述信息,结合上文比较容易理解,不再赘述。注意没有给新生成的项目指定version,会自动生成一个version。

执行命令后会生成新工程。遇到的坑:

(1)注意生成此命令需要新建一个空文件,在空文件中执行此命令,否则会报错;

(2)遇到了[ERROR] Failed to execute goal pl.project13.maven:git-commit-id-plugin:3.0.1:revision (get-git-infos) on project odl-helloworld: Could not complete Mojo execution...: Error: Could not get HEAD Ref, are you sure you have some commits in the dotGitDirectory? -> [Help 1]一个错误。经过查询资料,发现是pom引用了git-commit-id-plugin插件,此插件的作用是对git的不同版本做出标记,但当前helloword工程是生成的模板工程,所以自然没有.git文件,所以会报错。很奇怪的是,经过查询插件的pom语法,可以通过skip跳过此插件执行,或者可以通过failOnNoGitDirectory设置为false来跳过没有.git的文件,但无论如何设置,都不起效果。我也尝试在工程的pom文件中寻找使用此插件的位置,想通过直接删除掉对此插件的依赖来解决问题,但无论如何也没有搜到哪里使用,估计是跟父工程继承的属性有关系,父工程还没有仔细研究,待后面再看吧。当前实际解决问题的方法是在有需要的目录中增加了git文件,具体通过以下命令:

Solution:

Run in the project directory: git init && git add . && git commit -m 'initial commit'

If an error occurs, run: git config --global user.email 邮箱地址

And then, re-run mvn

是参考了老外的文章:https://nimli-computer.blogspot.com/2019/10/?m=0

需要科学上网才可以看。总结此问题,解决有三个方向:第一,修改此插件,使其能正常跳过没有git的文件;第二,修改工程pom,使工程去掉对此插件的依赖;第三,在需要.git的目录下建立合适的.git。由于第一,第二方法没有搞通,所以选择了第三种方法,其实第三种不是最佳方式,但至少可以解决编译不过的问题。让我们快速把精力投放在更有用的地方。

今天继续review了此问题,上文中第一种方法难度较大,也不是最佳解,本次直接尝试在第二种方法上做突破。排查helloword项目文件中每个子模块的pom文件,发现他们各自继承的父pom都不一样,所以修改父pom不太方便,从继承的角度看也不太合理。所以在每个项目中通过mvn help:effective-pom查看当前继承和聚合后的pom文件样式,从中找到git-commit-id-plugin对应的配置,我们的期望是去掉此plugin,因为无法在父pom中删除此插件依赖,所以只能在子项目中跳过此插件的执行,好在查看此插件的文档发现,可以在configure中通过<skip>true</skip>对其进行跳过处理。方法已经找到,则将通过mvn help:effective-pom查询到的pom文件中,将git-commit-id-plugin相关的内容拷贝出来,并在其中加上skip跳过,并把修改好的这段代码加入工程的pom文件中,注意对于此项目,plugin包含在plugins中,plugins包含在build中。再次编译就可以通过了!

(3)很多文件是windows格式,即换行按CR\LF切换,导致编译失败,使用notepad++中的“编辑” -> “文件格式转换”转成unix格式即可;

(4)会下载很多依赖文件到本地MAVEN仓库,由于网速问题,一个是慢,另一个可能中途断线导致失败,需要多次尝试。另外,也试用了网上的方法,将中央仓库地址配置为阿里云MAVEN仓库镜像地址,下载确实很快,但是出现了一堆乱七八糟的问题,比如某个库版本不匹配,某个库找不到,怀疑是阿里云仓库跟真正的中央仓库还是没有完全同步,所以放弃了阿里云。好在下载的每个小包都不算大,最大的就68M,尝试几次就OK了。

 

【4.在新工程上做扩展开发】:

用IDEA打开新生成的工程,根据需求不同,这里开发的方式也就千差万别了。我本次尝试的比较简单,只改了cli命令。cli目录下sdnlab下的cli下有三个目录分别是api, commands和impl。其中api目录下定义的是一个接口,impl目录下内容是对api中接口的实现类,在此将接口中的方法做了改动,返回hello world!,commands中的类是真正接收和处理用户敲命令行的响应类。它的默认命令行为test-command,还带个-tA的参数。

综上,我只改了impl下的实现方法,返回hello world!而已。

 

【5.编译、安装、测试】:

通过mvn clean install -DskipTests编译安装并跳过测试。编译时间较长,错误较多。编译时间长一方面是因为错误多,每次修改后都需要重编译,且下载的内容多,很占时间。错误主要是windows文件格式和unix文件格式转换问题,还有引用包的顺序问题。模板默认生成的引用顺序不对,错误提示很到位,很容易定位和修改。总之编译和安装没有遇到太难解决的问题,就是耗时间。

测试遇到了难点,我原以为的测试,是跟C语言编程差不多,编写一个模块后,将模块替换到环境上,环境重新启动加载新编译的模块后进行调试。但这个思路我在ODL上没有实现,不知道应该如何提取编译后的“模块文件”,或者更准确的叫做feature文件。我原以为在helloword工程目录下的karaf\target\assembly\system中将sdnlab文件夹整体拷贝到环境上odl的system下,重启后通过feature:install就可以,但重启后找不到helloworld的feature,所以也没法安装。

后来在helloworld工程目录下karaf\target中找到了tar包,看了下大小跟opendaylight大小差不多。放到环境上解压运行后,可以安装helloword的feature!敲命令test-command -tA 123可以返回hello world!



【6.在官方odl的release版本中加入自编译feature】:

由于项目需要,今天研究了上次没有搞定的事情,即如何将自编译的feature如c语言生成的模块一样加入到官方原始安装包中。

首先需要将自己写的odl工程编译通过,然后在项目目录下的helloworld/karaf/target/assembly/system中进行查找(我已经把工作系统从win迁移到mac os了,所以我的实际目录是/Users/lyd/WorkSpace/JavaWorkSpace/opendaylight/helloworld/karaf/target/assembly/system,其中helloworld是我工程所在目录,karaf是编译成功后生成的目录),

可以看到sdnlab文件夹,在进入sdnlab文件夹查看,生成的文件全在这里:

将sdnlab文件夹拷贝到官方release版本的system目录下,即把我们自编译的feature(模块)放在了官方版本的目录下。然后启动odl,通过命令:

feature:repo-add mvn:sdnlab/features-helloworld/0.1.0-SNAPSHOT/xml/features

将自编译feature(模块)读取到版本中,注意这一步是读取,不是加载,目的是让odl知道还有我们这样一个模块。此步骤命令中,黑色字体为固定命令,无需修改,红色字体需要按照自己的项目进行修改,其中sdnlab对应的是文件夹名字,真实项目中常用com.xxx.xxx,所以生成的文件夹也是com.xxx.xxx,features-helloworld是生成的文件夹下的features名字,仅此一个feature,0.0.1-SNAPSHOT是features-helloworld目录下的文件夹名称,代表了版本,以上就是红色字体的来源。然后在odl上通过命令:

feature:install features-helloworld

对feature进行安装,如果不报错就是安装成功,可以测试cli命令行。可以成功执行:

【7.在官方odl的release版本中设置自编译feature自启动】:

步骤6是步骤7的前提,当执行完步骤6后,进入odl下的etc文件夹,编辑org.apache.karaf.features.cfg文件,在featuresBoot后面加上自编译feature名称,如下图所示:

然后再在odl的etc目录下的查找与org.apache.karaf.features.cfg中featuresRepositories =后面的一串数字相同的xml文件,如下图:

vi进去,如下图添加自编译feature两项配置(注意此图圈注有误!!!上面那个圈应该是第6行,不是第7行,第7行是默认就有的,不能改!!!)

修改后保存,启动odl,查询自编译feature,已经成功自动启动:

再查看在自编译feature代码中,默认启动会执行的init函数中打印的日志是否成功打印:

日志在odl的data/log目录下:

在日志中查找打印信息,可以成功找到:

说明自动启动时会执行init函数,我们可以在init函数中做一些我们希望初始化的事情。

 

参考信息:

https://www.sdnlab.com/19931.html

https://blog.csdn.net/Kangyucheng/article/details/91393302

文章来自个人专栏
SDN
2 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0