50

DLUX组件扩展下篇-实践

 5 years ago
source link: https://www.sdnlab.com/22471.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作者: M.S-Group.皮皮熊,M.S-Group组织主要成员之一,数通行业老兵,精通传统数通网络技术,SDN/NFV新技术的狂热拥护者!

DLUX668.jpg

一、文章目标

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文件中:

Java
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
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文件。

Java

文件内容: <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;

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) 中,修改两处:

Java

<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> ……

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配置工程文件:

Java
Dluxapps Features Features-dluxapps Odl-dluxapps-cowin Odl-dluxapps-topology Odl-dluxapps-yangman ……
1
2
3
4
5
6
7
Dluxapps
Features
Features-dluxapps
Odl-dluxapps-cowin
Odl-dluxapps-topology
Odl-dluxapps-yangman
……

Pom.xml文件如下:

Java

<?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>

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"?>
<!--
Copyright2017Red Hat,Inc.andothers.
 
Thisprogram andthe accompanying materials are made available under the
terms of the Eclipse PublicLicense v1.0which accompanies thisdistribution,
andisavailable 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 isused by autorelease toparse andnotify projects on
         build failure.Please donotmodify thisunless you haveagood 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的目录:
DLUX-1.png
参考topology目录,确定相关文件:

2.2.1 Blueprint.xml(在cowin-bundle目录下):

Java

<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>

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">
      <propertyname="httpService"ref="httpService"/>
      <propertyname="loader"ref="loader"/>
      <propertyname="moduleName"value="cowin"/>
      <propertyname="url"value="/src/app/cowin"/>
      <propertyname="directory"value="/cowin/build"/>
      <propertyname="requireJs"value="app/cowin/cowin.module"/>
      <propertyname="angularJs"value="app.cowin"/>
      <propertyname="cssDependencies">
          <list>
                <value>src/app/cowin/cowin.css</value>
          </list>
      </property>
    </bean>
</blueprint>

2.2.2 Cowin.tpl.html文件(cowin-module目录下):

Java

<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>

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文件:

Java

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; });

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){
  varcowin=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"
      }
    });
    varaccess=routingConfig.accessLevels;
    $stateProvider.state('main.cowin',{
      url:'cowin',
      access:access.public,
      views:{
        'content':{
          templateUrl:'src/app/cowin/cowin.tpl.html',
          controller:'CowinCtrl'
        }
      }
    });
  });
  returncowin;
});

2.2.4 Cowin.controller.js

Java

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); }); }; }]); });

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(){
              varoldList=$scope.todoList;
              $scope.todoList=[];
              angular.forEach(oldList,function(x){
                  if(!x.done)$scope.todoList.push(x);
              });
          };
      }]);
});

2.2.5 Cowin.less

Java
.cowin-bk{ background-color: #269abc; }
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解压到本地,文件内容包括:
DLUX-2.png
其它的modules组件在对应的dluxapps目录下,类似方式解压到对应目录即可。
构建目录架构,如图所示:

DLUX-3.png

其中:
①、②就是dlux-Modules-loader-resources下文件
③是assets下image文件,需要将logo 文件放置在该目录
④将dluxapps的新建的module cowin相关文件拷贝放置该目录

2.5 编译完成,并在karaf中install

2.5.1 编译

编译,在dluxapps目录下,运行:

Java
mvn clean install -DskipTests -Dcheckstyle.skip=true -Dmaven.javadoc.skip=true
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
如下所示:

DLUX-4.png

C:安装
命令: feature:install odl-dluxapps-cowin
如下所示:

DLUX-5.png

2.6 web打开

输入:http://20.0.0.22:8181/index.html,其中20.0.0.22为ODL运行服务器IP。

DLUX-6.png

至此,一个全新的dlux module Cowin完全安装成功!

四、其它说明

介于篇幅所限,文章只把关键的步骤和过程中,自己碰到的坑,都详细记录。但是还有比较多的如工程pom.xml文件配置等,未涉及,只要参考类似模块,应该可以顺利完成。
文中涉及的扩展工程,方便大家参考,尽力使用了完整文档,且可以直接拷贝使用。为了节省时间,需要工程代码的同学,可以加微信直接提供参考代码,进行学习交流。
微信二维码,请在添加时备注:SDN学习交流。

DLUX34_200.jpg


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK