1.Yang 中涉及到的
RPC 和Notification概念
对一个对象进行建模基本都包含三个部分:
一:对象的数据结构
二:可以对该对象进行的操作(rpc)
三:该对象可以做出响应(notification)
而yang里面的rpc就是定义了一系列操作,而notification就是定义了一系列的通知事件。
而rpc和notification的机制,简单理解就是:rpc是函数调用,notification是事件监听。
这是简单的理解。
对一个对象进行建模基本都包含三个部分:
一:对象的数据结构
二:可以对该对象进行的操作(rpc)
三:该对象可以做出响应(notification)
而yang里面的rpc就是定义了一系列操作,而notification就是定义了一系列的通知事件。
而rpc和notification的机制,简单理解就是:rpc是函数调用,notification是事件监听。
这是简单的理解。
2. Yang中typedef关键字
typedef这个关键字简单理解就是把一个基类包装成一个包装类的意思。做个类比就像 java里有int类型,对应的包装类是Integer类。
typedef DisplayString {
type string {
length "0 .. 255";
}
description
"YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
reference
"RFC 2579, section 2.";
}
这种写法首先可以给这个string类型一个明确的含义,因为它有了一个名字叫DisplayString,这样别人使用它的时候就知道是干什么的了。。如果没有这个包装类都只用基类,你想想这个代码的可读性有多差。
至于生成的java代码里实现了一个序列化的接口Serializable(应该不是叫串行化吧),这一点首先我们暂时用不到其实可以不关心的,但它这么做是有好处的,因为java中基础类型都是可以直接被序列化的,而自定义的类如果不实现序列化的接口,在使用序列化传输的场合是会出问题的。所以yangtools并不确定你使用它生成的java代码的用途,所以它尽可能的帮你多做一些事情,可以让其生成的java代码适用范围更广。
关于序列化的适用场合大家自行百度就可以了,也不是一句两句可以说清的。总之,多了这个接口并不会造成什么歧义,大家尽量关注其主要的功能就可以了。
typedef这个关键字简单理解就是把一个基类包装成一个包装类的意思。做个类比就像 java里有int类型,对应的包装类是Integer类。
typedef DisplayString {
type string {
length "0 .. 255";
}
description
"YANG version of the SMIv2 DisplayString TEXTUAL-CONVENTION.";
reference
"RFC 2579, section 2.";
}
这种写法首先可以给这个string类型一个明确的含义,因为它有了一个名字叫DisplayString,这样别人使用它的时候就知道是干什么的了。。如果没有这个包装类都只用基类,你想想这个代码的可读性有多差。
至于生成的java代码里实现了一个序列化的接口Serializable(应该不是叫串行化吧),这一点首先我们暂时用不到其实可以不关心的,但它这么做是有好处的,因为java中基础类型都是可以直接被序列化的,而自定义的类如果不实现序列化的接口,在使用序列化传输的场合是会出问题的。所以yangtools并不确定你使用它生成的java代码的用途,所以它尽可能的帮你多做一些事情,可以让其生成的java代码适用范围更广。
关于序列化的适用场合大家自行百度就可以了,也不是一句两句可以说清的。总之,多了这个接口并不会造成什么歧义,大家尽量关注其主要的功能就可以了。
3.Yang例子简析, “#”--添加的专门注释
例:
// vi: set smarttab et sw=4 tabstop=4:
module toaster-provider-impl {
# Yang的版本
yang-version 1;
# 命名空间,此地址重要,Yang自动生成的文件会放在这个 namespace+Version版本生成的目录下面
# 但是这边举例有些特殊,待会会说到这个情况。
namespace "urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl";
#此处是说明此Yang文件的前缀
prefix "toaster-provider-impl";
// vi: set smarttab et sw=4 tabstop=4:
module toaster-provider-impl {
# Yang的版本
yang-version 1;
# 命名空间,此地址重要,Yang自动生成的文件会放在这个 namespace+Version版本生成的目录下面
# 但是这边举例有些特殊,待会会说到这个情况。
namespace "urn:opendaylight:params:xml:ns:yang:controller:config:toaster-provider:impl";
#此处是说明此Yang文件的前缀
prefix "toaster-provider-impl";
#import 导入,和Java导入的一样。此处导入的是分别是config.yang,rpc-context.yang,opendaylight-md-sal-binding
#同时标注好了相应的简称和版本,列如rpc-context.yang就可以用“rpcx”替代。(
注:这里是怎么通过import找到要导入的文件?bundle是如何启动 时处理的?这些暂时不说明,这个涉及到bundle启动时的机制)
import config { prefix config; revision-date 2013-04-05; }
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
#描述信息,作为一个Yang语言中的注释,就好像Java中的@doc
description
"This module contains the base YANG definitions for
toaster-provider impl implementation.";
#版本信息,一般是XXXX-XX-XX 格式的时间。
revision "2014-01-31" {
description
"Initial revision.";
}
#这边namespace和revision已经给出,一般来说,生成的Java文件会放到如下的文件目录
import rpc-context { prefix rpcx; revision-date 2013-06-17; }
import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
#描述信息,作为一个Yang语言中的注释,就好像Java中的@doc
description
"This module contains the base YANG definitions for
toaster-provider impl implementation.";
#版本信息,一般是XXXX-XX-XX 格式的时间。
revision "2014-01-31" {
description
"Initial revision.";
}
#这边namespace和revision已经给出,一般来说,生成的Java文件会放到如下的文件目录
#org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.toaster.provider.impl.rev140131
#这下面是Yang语言作为数据建模语言的主要内容了,接下来的内容分析比较多,看下面具体的分析。
// This is the definition of the service implementation as a module identity.
identity toaster-provider-impl {
base config:module-type;
// Specifies the prefix for generated java classes.
config:java-name-prefix ToasterProvider;
}
// Augments the 'configuration' choice node under modules/module.
augment "/config:modules/config:module/config:configuration" {
case toaster-provider-impl {
when "/config:modules/config:module/config:type = 'toaster-provider-impl'";
container rpc-registry {
uses config:service-ref {
refine type {
mandatory true;
config:required-identity mdsal:binding-rpc-registry;
identity toaster-provider-impl {
base config:module-type;
// Specifies the prefix for generated java classes.
config:java-name-prefix ToasterProvider;
}
// Augments the 'configuration' choice node under modules/module.
augment "/config:modules/config:module/config:configuration" {
case toaster-provider-impl {
when "/config:modules/config:module/config:type = 'toaster-provider-impl'";
container rpc-registry {
uses config:service-ref {
refine type {
mandatory true;
config:required-identity mdsal:binding-rpc-registry;