作者: M.S-Group.皮皮熊,M.S-Group组织主要成员之一,数通行业老兵,精通传统数通网络技术,SDN/NFV新技术的狂热拥护者!
一、文章目标
1.1目标
随着SDN技术的逐步成熟,大量的传统数通厂家和新型的IT厂家,都投入了一定的人员进行相关的产品技术预研。而ODL作为SDN控制器的主要开源项目,自然也成了多数人学习和搭建模拟环境试验的首选。但是,从本人切入了解、学习以及在此上面,完成产品预研的经历看,由于文档缺失、网上各种文章质量不等,从搭建环境、理解框架工作机制到完成模块扩展定制,花了大量的时间,因此特整理此文,希望从代码组织、工作原理及扩展实践几个维度,系统的说明相关步骤,以方便后续人员了解、少走弯路、节省时间!
另外,开源系统自带的DLUX相关组件,由于界面比较简约,个人认为主要价值是示例性质、各团队若在ODL基础上,进一步研发自己的产品,势必会进行组件扩展,因此也希望本扩展用例能再这方面也产生一定的推进作用。
1.2文章环境及版本
Linux:ubuntu 4.15.0-34-generic
Java :1.8.0_144
ODL :release/carbon-sr4
代码下载:
git clone –b release/carbon-sr4 https://git.opendaylight.org/gerrit/dlux
git clone –b release/carbon-sr4 https://git.opendaylight.org/gerrit/dluxapps
1.3 所需背景知识
参考:DLUX组件扩展上篇-原理
需要了解: DLUX 组件注册的view的动态添加、UI-Route状态设置、nav菜单添加、Sec-logo设置、编译工程依赖等信息。
二、扩展新组件
本节以增加新feature组件dlux-apps-cowin为例,逐步详细介绍各个步骤:
2.1新Feature添加
./karaf(ODL的服务器端运行命令),系统默认加载的feature信息配置文件为当前目录的../etc/org.apache.karaf.features.cfg文件中:
1 |
featuresRepositories = mvn:org.apache.karaf.features/standard/3.0.8/xml/features,mvn:org.apache.karaf.features/enterprise/3.0.8/xml/features,mvn:org.ops4j.pax.web/pax-web-features/3.2.9/xml/features,mvn:org.apache.karaf.features/spring/3.0.8/xml/features,mvn:org.opendaylight.integration/features-integration-index/0.6.4-Carbon/xml/features |
其中,红色标记为加载的opendaylight的集成feature信息,上述文件对应:
/home/sdn/opendaylight/distribution-karaf-0.6.4-Carbon/system/org/opendaylight/integration/features-integration-index/0.6.4-Carbon/ eatures-integration-index-0.6.4-Carbon-features.xml文件。
1 2 3 4 5 6 7 8 9 10 11 |
文件内容: <repository>mvn:org.opendaylight.controller/mdsal-trace-features/1.5.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.didm/features-didm/0.4.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.didm/features-didm-hp/0.4.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.didm/features-didm-ovs/0.4.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.dlux/features-dlux/0.5.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.dluxapps/features-dluxapps/0.5.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.eman/eman-features/1.1.4-Carbon/xml/features</repository> <repository>mvn:org.opendaylight.faas/features-faas/1.2.4-Carbon/xml/features</repository> 因此,配置和增加dluxapps/features-dluxapps中描述即可扩展feature; |
在Features.xml (dluxapps\features\features-dluxapps\src\main\features) 中,修改两处:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
<feature name='odl-dluxapps-applications' version='${project.version}' description="Opendaylight DluxApps all applications"> <feature>odl-dluxapps-nodes</feature> <feature>odl-dluxapps-topology</feature> <feature>odl-dluxapps-cowin</feature> <feature>odl-dluxapps-yangui</feature> <feature>odl-dluxapps-yangvisualizer</feature> <feature>odl-dluxapps-yangman</feature> </feature> …… <feature name="odl-dluxapps-topology" version='${project.version}' description="Enable nodes in Opendaylight dlux"> <feature version="${dlux.version}">odl-dlux-core</feature> <bundle>mvn:org.opendaylight.dluxapps/topology-bundle/{{VERSION}}</bundle> </feature> <feature name="odl-dluxapps-cowin" version='${project.version}' description="agile sdn solution"> <feature version="${dlux.version}">odl-dlux-core</feature> <bundle>mvn:org.opendaylight.dluxapps/cowin-bundle/{{VERSION}}</bundle> </feature> …… |
确保在./karaf的控制台下,使用
Feature:list | grep dlux 可以发现odl-dluxapps-cowin组件。
在当前目录下,增加Odl-dluxapps-cowin目录,如下,并参考topology目录下pom.xml配置工程文件:
1 2 3 4 5 6 7 |
Dluxapps Features Features-dluxapps Odl-dluxapps-cowin Odl-dluxapps-topology Odl-dluxapps-yangman …… |
Pom.xml文件如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
<?xml version="1.0" encoding="UTF-8"?> <!-- Copyright 漏 2017 Red Hat, Inc. and others. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html --> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.opendaylight.odlparent</groupId> <artifactId>single-feature-parent</artifactId> <version>1.8.4-Carbon</version> <relativePath/> </parent> <groupId>org.opendaylight.dluxapps</groupId> <artifactId>odl-dluxapps-cowin</artifactId> <version>0.5.4-Carbon</version> <packaging>feature</packaging> <!-- <name> formatting is used by autorelease to parse and notify projects on build failure. Please do not modify this unless you have a good reason. --> <name>ODL :: dluxapps :: ${project.artifactId}</name> <dependencies> <dependency> <groupId>org.opendaylight.dlux</groupId> <artifactId>odl-dlux-core</artifactId> <version>0.5.4-Carbon</version> <type>xml</type> <classifier>features</classifier> </dependency> <dependency> <groupId>${project.groupId}</groupId> <artifactId>cowin-bundle</artifactId> <version>${project.version}</version> </dependency> </dependencies> </project> |
2.2 新模块的注册
如图,在dluxapps/Applications目录下,创建对应Cowin的目录:
参考topology目录,确定相关文件:
2.2.1 Blueprint.xml(在cowin-bundle目录下):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"> <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/> <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/> <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule"> <property name="httpService" ref="httpService"/> <property name="loader" ref="loader"/> <property name="moduleName" value="cowin"/> <property name="url" value="/src/app/cowin"/> <property name="directory" value="/cowin/build"/> <property name="requireJs" value="app/cowin/cowin.module"/> <property name="angularJs" value="app.cowin"/> <property name="cssDependencies"> <list> <value>src/app/cowin/cowin.css</value> </list> </property> </bean> </blueprint> |
2.2.2 Cowin.tpl.html文件(cowin-module目录下):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<div class="container cowin-bk" > <h2 > 我的备忘录 </h2> <form ng-submit="todoAdd()"> <input type="text" ng-model="todoInput" size="50" placeholder="新增"> <input type="submit" value="新增"> </form> <br> <div ng-repeat="x in todoList"> <input type="checkbox" ng-model="x.done"> <span ng-bind="x.todoText"></span> </div> <p><button ng-click="remove()">删除记录</button></p> </div> |
2.2.3 Cowin.module.js文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
define(['angularAMD', 'app/routingConfig', 'app/core/core.services','Restangular', 'common/config/env.module'], function(ng) { var cowin = angular.module('app.cowin', ['ui.router.state','app.core','restangular', 'config']); cowin.config(function($stateProvider, $translateProvider, $urlRouterProvider, NavHelperProvider) { $urlRouterProvider.otherwise('/cowin'); NavHelperProvider.addControllerUrl('app/cowin/cowin.controller'); NavHelperProvider.addToMenu('cowin', { "link": "#/cowin", "title": "CoWin SDN", "active": "main.cowin", "icon": "icon-level-down", "page": { "title": "COWIN", "description": "COWIN" } }); var access = routingConfig.accessLevels; $stateProvider.state('main.cowin', { url: 'cowin', access: access.public, views : { 'content' : { templateUrl: 'src/app/cowin/cowin.tpl.html', controller: 'CowinCtrl' } } }); }); return cowin; }); |
2.2.4 Cowin.controller.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
define(['app/cowin/cowin.module','app/cowin/cowin.services'], function(cowin, service) { cowin.controller('CowinCtrl', ['$scope', '$rootScope', function ($scope, $rootScope) { $rootScope['section_logo'] = 'assets/images/logo_cowin.gif'; $scope.todoList = [{todoText:'Clean House', done:false}]; $scope.todoAdd = function() { $scope.todoList.push({todoText:$scope.todoInput, done:false}); $scope.todoInput = ""; }; $scope.remove = function() { var oldList = $scope.todoList; $scope.todoList = []; angular.forEach(oldList, function(x) { if (!x.done) $scope.todoList.push(x); }); }; }]); }); |
2.2.5 Cowin.less
1 2 3 |
.cowin-bk{ background-color: #269abc; } |
设置背景为淡蓝色。
2.3 新模块需要的资源的放置
在src\asserts\images下,放置:logo_cowin.gif文件
修改gulp.js的build.config.js文件,确保工程构建时,拷贝到对应的asserts目录下。
2.4 根据运行web服务目录构建本地调试环境
见2.2 web服务目录结构,拷贝ODL工程目录下对应的jar包并解压到相应目录:
如:
默认build 并install的工程目录为Linux下当前用户根目录.m2下:
~/.m2/repository/org/opendaylight/dlux/dlux.loader.resources/0.5.4-Carbon/
dlux.loader.resources-0.5.4-Carbon.jar,使用tar解压到本地,文件内容包括:
其它的modules组件在对应的dluxapps目录下,类似方式解压到对应目录即可。
构建目录架构,如图所示:
其中:
①、②就是dlux-Modules-loader-resources下文件
③是assets下image文件,需要将logo 文件放置在该目录
④将dluxapps的新建的module cowin相关文件拷贝放置该目录
2.5 编译完成,并在karaf中install
2.5.1 编译
编译,在dluxapps目录下,运行:
1 |
mvn clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true |
确认编译成功即可。
2.5.2 安装
A:su运行./karaf
B:在控制台,查看dlux相关的feature
命令: feature:list | grep dlux
如下所示:
C:安装
命令: feature:install odl-dluxapps-cowin
如下所示:
2.6 web打开
输入:http://20.0.0.22:8181/index.html,其中20.0.0.22为ODL运行服务器IP。
至此,一个全新的dlux module Cowin完全安装成功!
三、其它说明
介于篇幅所限,文章只把关键的步骤和过程中,自己碰到的坑,都详细记录。但是还有比较多的如工程pom.xml文件配置等,未涉及,只要参考类似模块,应该可以顺利完成。
文中涉及的扩展工程,方便大家参考,尽力使用了完整文档,且可以直接拷贝使用。为了节省时间,需要工程代码的同学,可以加微信直接提供参考代码,进行学习交流。
微信二维码,请在添加时备注:SDN学习交流。