OpenDayLight开发(3)-DataStoreChange监听器三种类型

2016-01-15 by Guangze Zhao

OpenDayLight中的所有数据都保存在DataStore中,并且数据以树形结构存储,可参考OpenDayLight开发(2)中的介绍。外界对DataStore的访问有BA和BI两种方式,这两种方式具有映射关系,BI像是BA的底层实现,通过QName实现对数据的索引,而BA更像是在BI上的封装,不能以BI的方式对数据进行准确的索引,但是提供了更方便的调用接口等。

映射关系

由于数据存储在DataStore中,因此ODL中对DataStore的访问非常重要。DataStore的变化会触发DataStoreChange事件的发生,设置监听器收到变化事件后触发任务是ODL的运行机制。最近研究了三种Listener类型: DataChangeListener, DataTreeChangeListener, DomDataTreeChangeListener.

DataChangeListener

DataChangeListener是最简单的使用方式。Toaster中用的就是这种Listener,使用Binding-aware方式访问DataStore,具体调用方式在ODL(2)中有了说明,这里不再重复。其中需注意的是数据通过IID(InstanceIdentifier)作为索引/标识。使用DataChangeListener往往需要对整颗树进行监听,树中任何一个叶子节点的变化都会触发DataChangeListener事件。

DataTreeChangeListener

DataTreeChangeListener,数据的标识在IID的基础上,进一步精确,通过DataTreeIdentifier进行数据在树型结构中存储位置的定位。通过DataTreeIdentifier可以定位到树中的树干,可以进行更精确的变化位置的监听。使用方式:

Implement: 
    class VlanProvider implements DataTreeChangeListener<Vlan>

Identifier: 
    InstanceIdentifier<vlan> Vlan_IID = InstanceIdentifier.builder(Device.config.class).child(Switch.class).child(vlan.class);

    DataTreeIdentifier<vlan> vlan_path = new DataTreeIdentifier<>(LogicalDatastoreType.CONFIGURATION, Vlan_IID);

Register Listener with DataBroker:
    this.VlanListener = dataBroker.registerDataTreeChangeListener(vlan_path, this);

首先当前类实现DataTreeChangeListener接口,然后声明DataTreeIdentifier,最后注册监听器。监听函数代码如下:

public void onDataTreeChanged(Collection<DataTreeModification<Vlan>> changed){

    for(final DataTreeModification<Vlan> change: changed){
        final DataObjectModification<Vlan> rootChange = change.getRootNode();
        switch(rootChange.getModificationType()){
            case WRITE:
                LOG.info("Write - before : {} after : {}", rootChange.getDataBefore(), rootChange.getDataAfter());
                break;
            case SUBTREE_MODIFIED:
                LOG.info("Write - before : {} after : {}", rootChange.getDataBefore(), rootChange.getDataAfter());
                break;
            case DELETE:
                LOG.info("Write - before : {} after : {}", rootChange.getDataBefore(), rootChange.getDataAfter());
                break;
        }
    }
}

通过getRootNode()获取当前变化节点,getModificationType()获得数据树变化类型,分三种:WRITE, SUBTREE_MODIFIED, DELETE。写入,子树变化,或删除。getDataBefore()获得变化前的数据,getDataAfter()获得变化后的数据。

DOMDataTreeChangeListener

通过DOMDataBroker访问DataStore,使用Binding Independent类型,使用QName对数据树进行索引和数据的定位。相关名词:

  • DOMDataBroker
  • DOMDataWriteTransaction
  • YangInstanceIdentifier
  • DataTreeChange(DOMDataTreeChange)
  • Transaction Chain

具体代码如:

DOMDataWriteTransaction tx = domDataBroker.newWriteOnlyTransaction();

YangInstanceIdentifier yid = YangInstanceIdentifier.builder().node(TestExec.QNAME).node(OuterList.QNAME).nodeWithKey(OuterList.QNAME, element.getId()).build();

tx.put(LogicalDatastoreType.CONFIGURATION, yid, element);

try {
    tx.submit().checkedGet();
} catch( TransactionCommitFailedException e){
    LOG.error("Transaction failed: {}", e.toString());
}

使用BI方式,通过QNAME进行索引,可对数据树中的任何位置进行精确的定位,直接获取QNAME对应位置的变化事件。


Comments

Fork me on GitHub