snowwhite
OpenDaylight开发-从Toaster例子学习Rpc,Notification,DataStore
 

=========================================================================================== 

新的理解汇总本文:

  • Rpc:提供服务的远程调用接口
  • Notification:提供通知,可以发出通知和接收通知。
  • DataStore:提供数据存储,读取,Transaction等功能。
  • Request Routing:提供请求路由功能,把外部请求传送到正确的Plugin和Node instance处理。(请求路由)
  • Node instance:Yang结构树上的节点实例
  • Restconf Subsystem:自动定义和创建Restconf API的Plugin
  • Config subsystem:提供统一的配置文件管理功能的Plugin

 

  Rpc可以理解北向调用模型的相关服务接口;

 

   Yang模型中有:container, list, leaf数据类型

 

===========================================================================================

概述

  OpenDaylight的服务抽象层(SAL)早期的编程模型是API驱动(AD-SAL),北向API一一对应南向协议,使得AD-SAL开发的北向应用程序只能依赖唯一的南向协议,不具备通用性。后来编程模型改为模型驱动,即MD-SAL,本人主要接触的也是MD-SAL,并没有基于AD-SAL做过开发。MD-SAL通过Yang Model定义模型,北向应用程序与模型交互,模型与网络交互。

关于MD-SAL

  • MD-SAL模型驱动的服务抽象层,为Apps和Plugins开发提供同意支持
  • 提供Request Routing和用来实现抽象服务和相应API的基础框架
  • 抽象服务和API都由各个Plugin通过Yang Model定义
  • Yang Tools Plugin根据Yang Model的定义自动生成API,生成相应Java代码
  • 开发者通过实现自动生成的Service Interface来实现具体的API功能和服务内容
  • Plugin通过MD-SAL和生成的API(Rpc,Notification),DataStore去利用其他Plugin的服务和数据
  • 所有功能模块的信息交互,数据存储调用都通过MD-SAL完成

名词解释

  • Rpc:提供服务的远程调用接口
  • Notification:提供通知,可以发出通知和接收通知。
  • DataStore:提供数据存储,读取,Transaction等功能。
  • Request Routing:提供请求路由功能,把外部请求传送到正确的Plugin和Node instance处理。(请求路由)
  • Node instance:Yang结构树上的节点实例
  • Restconf Subsystem:自动定义和创建Restconf API的Plugin
  • Config subsystem:提供统一的配置文件管理功能的Plugin

MD-SAL Plugin

Plugin与MD-SAL的关联方式可分成两种:

1.BA(Binding-Aware) 使用Yang Model定义模型,并自动生成的Java Bindings的Plugin
2.BI(Binding-Independent) 与BA不同,不依赖于Java Bindings

Yang Model

Yang Model可以定义三种类型:Rpc,Notification,Data。

Rpc可以理解北向调用模型的相关服务接口

Notification为通知,通常用于发送某种事件而广播通知,或订阅通知收到通知后的操作;

Data为数据,Yang Model中可以定义数据类型并存储数据,data分两种:Config和Operational。

  Config为配置信息,北向应用向南向网络下发的配置数据信息,Operational为运行时信息,通常是ODL记录的南向的网络状态信息。

Yang Model详细语法规则,参照https://tools.ietf.org/html/rfc6020

Rpc

Rpc definitions in YANG
Toaster例子中,在toaster-api目录下的Yang文件中定义了三个rpc:make-toast, cancel-toast, restock-toaster。对应实现了三个功能:烤面包,取消烧烤,重新填装。烤面包操作需输入两个参数:熟的程度和面包类型。取消烧烤没有输入输出。重新填装需输入重新填装的数量。

Rpc registration
在api/目录下写完Yang Model后编译,自动生成Java Code, Rpc对应ToasterService

在toaster-impl/中需实现ToasterService接口 

1 public class ToasterImpl implements ..., ToasterService, ...{}

然后在注册Rpc

1 @Override
2 public void onSessionInitiated(ProviderContext session){
3     //Register the RPC Service
4     rpcReg = session.addRpcImplementation(ToasterService.class, this);
5     ...
6 }

 

Rpc implementation
最后实现Rpc的功能,e.g. make-toast

Notification

在Yang Model中定义

在SAL中注册 

发送通知

1 if(outOfBread()) {
2     notificationService.publish(new ToasterOutOfBreadBuilder().build());
3 }

 

编译api/,YangModel中定义的notification会自动生成Listener接口ToasterListener,订阅收到通知后的操作需实现该接口,如下是自动生成的ToasterListener代码。

DataStore

Yang Data Tree
MD-SAL中通过DataStore存储数据,与DataStore的交互通过DataBroker实现,DataStore中存储的数据发生变化会触发onDataChange()事件,在onDataChange()中响应DataStore的变化。数据在DataStore中以树形结构存储。 Yang模型中有:container, list, leaf数据类型。那么树形结构可能如:

使用DataBroker对DataStore进行数据读写,监听数据仓库变化事件。

  • 注册监听器dataBroker.registerDataChangeListener(LogicalDataStoreType, InstanceIdentifier, dataChangeListener, DataChangeScope)
  • LogicalDataStoreType:Configuration or Operational即DataStore中存储的数据类型,是Configuration或者Operational
  • DataChangeScope:BASE(change in node only), ONE(change in node or direct children), SUBTREE(change in node or direct children or nested children)监听变化范围,BASE只监听当前节点变化事件,ONE监听当前节点和其左右儿子节点变化事件,SUBTREE监听当前节点和左右子树的所有变化事件。
  • InstanceIdentifier是监听节点的身份标识。
  • Implement the onDataChange(final AsyncDataChangeEvent, DataObject> change)实现onDataChange函数。
  • AsyncDataChangeEvent has 4 APIs: getCreatedData, getUpdatedData, getOriginalData, getRemovedPaths.其作用是getCreatedData获取第一次创建DataStore并存入的数据。getUpdatedData获得更新后的数据,getOriginalData获得更新前的数据,getRemovedPaths获取删除以后的数据仓库。
  • 事务有三种,读,写,读写:ReadTransaction/ReadWriteTransaction/WriteTransaction

监听DataStore变化
为监听节点,创建身份标识Instance Identifier:

 

public static final InstanceIdentifier<Toaster> TOASTER_IID = InstanceIdentifier.builder(Toaster.class).build();

使用DataBroker注册监听器

dcReg = dataService.registerDataChangeListener( LogicalDatastoreType.CONFIGURATION, TOASTER_IID, this, DataChangeScope.SUBTREE)

监听数据变化 

从DataStore读取数据

 

@Override
public void onDataChange(final AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> change){
    DataObject dataObject = change.getUpdatedSubtree();
 
    if( dataObject instanceof Toaster) {
        Toaster toaster = (Toaster) dataObject;
        LOG.info("onDataChanged - new Toaster config: {}", toaster);
    } else {
        LOG.warn("onDataChange - not instance of Toaster {}", dataObject);
    }
}

l

向DataStore写入数据
1.Data:使用Yang模型自动生成的builder和setter方法创建数据。
2.Create:使用dataBroker创建writeTransaction
3.Put:将数据写入Transaction
4.Submit:提交Transaction

下面是同步方式写入

 

Toaster toaster = new ToasterBuilder().setToasterManufacturer( TOASTER_MANUFACTURER ).setToasterModelNumber(TOASTER_MODEL_NUMBER).setToasterStatus( ToasterStatus.Up).build();
 
WriteTransaction tx = dataService.newWriteOnlyTransaction();
 
tx.put(LogicalDatastoreType.OPERATIONAL, TOASTER_IID, toaster);
 
tx.submit();

 

下面是异步方式写入

 

总结

ODL wiki中Toaster是很好的入门OpenDayLight Plugin开发的例子,实现一遍Toaster,对刚刚入门的ODL学习者理解ODL非常受益,以上是我学习Toaster的一些总结,希望能给读者带来帮助。

分类:

技术点:

相关文章: