Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

0

How to handle Yang list in datastore of Opendaylight

asked 2016-04-06 04:20:58 -0700

Veinthrough gravatar image

updated 2016-04-06 18:18:30 -0700

I'm writing an application in ovsdb which integrated with Openstack Neutron. At first, I just implemented the basic function counting and summarize the networks created by Neutron. First, the Yang as follows:

    module skeleton {
    yang-version 1;
    namespace "urn:opendaylight:params:xml:ns:yang:ovsdb:web";

    prefix "ovsdb-web";

    contact
        "Yuqi Wang <wyqbupt@163.com>";

    description
        "YANG version of the MIB-file.";

    revision "2015-05-24" {
        description
            "skeleton module in progress.";
    }

    container Skeleton {
        presence
            "Indicates the  service is available";
        description
            "The container for all networks and the index .";
        list skeleton-network {
            description "network info";
            config false;
            key "index";
            leaf index {
                description "index of the network";
                type uint32;
            }
            leaf name {
                description "name of the network";
                type string;
            }
        }

        leaf num{
            type uint32;
            config false;
            default 0;
            description
                "number of networks";
        }
    }  // container
 }  // module

In the Container Skeleton, the leaf num is used to count the number of networks, and list skeleton-network is a list of description of each network which contains the name and the index.

The main part of implementation as follows:

    private List<SkeletonNetwork> getSkeletonNetworks(){
    final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class);
    ReadOnlyTransaction transaction= dataService.newReadOnlyTransaction();
    CheckedFuture<Optional<Skeleton>, ReadFailedException> future = transaction.read(LogicalDatastoreType.OPERATIONAL, instanceIdentifier);
    List<SkeletonNetwork> skeletonNetworks= null;
    if (future != null) {
        try {
            Skeleton skeleton = future.checkedGet().orNull();
            skeletonNetworks= skeleton.getSkeletonNetwork();
        } catch (ReadFailedException e) {
            LOG.info("Failed to read {}", instanceIdentifier, e);
        }
    }
    transaction.close();
    LOG.info("[END]getSkeletonNetworks, skeletonNetworks: {}", skeletonNetworks);
    return skeletonNetworks;
}

private boolean writeSkeletonNetwork( String networkName, Long index) {
    LOG.info("[BEGIN]writeSkeletonNetwork, networkName: {}, index: {}", networkName, index);
    SkeletonNetwork network= new SkeletonNetworkBuilder()
        .setName( networkName)
        .setIndex( index)
        .build();

    LOG.info("[IN]writeSkeletonNetwork, BEFORE transact:");
    LOG.info("    networkName: {}, index: {}, key: {}", network.getName(), network.getIndex(), network.getKey());

    final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class)
                                                  .child(SkeletonNetwork.class, network.getKey());
    final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
    transaction.put( LogicalDatastoreType.OPERATIONAL, instanceIdentifier, network, true);


    CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
    try {
        future.get();
    } catch (InterruptedException | ExecutionException e) {
        LOG.warn("Transation failed ",e);
        return false;
    }

    List<SkeletonNetwork> skeletonNetworks= getSkeletonNetworks();
    LOG.info("[IN]writeSkeletonNetwork, AFTER transact:");
    for( SkeletonNetwork skeletonNetwork : skeletonNetworks){
        LOG.info("    networkName: {}, index: {}, key: {}", skeletonNetwork.getName(), skeletonNetwork.getIndex(), skeletonNetwork.getKey());
    }
    LOG.info("[END]writeSkeletonNetwork");
    return true;
}

The results from web looks well: when I created a network named "test1": web1 when I created the 2nd network named "test2": web2

However, I have 2 problems:

  1. why the list skeleton-network is not displayed in the url "http://10.10.51.124:8181/restconf/operational/skeleton:Skeleton" and how can I access it? Is "http://10.10.51.124:8181/restconf/operational/skeleton:Skeleton/skeleton-network/index:1" right? web3

  2. It seems that the datastore is in wrong state: log1

    log2

that is, the content in the list doesn't contain test1 and test2, but only the latest created one test2. Therefore, I'm wondering whether the write-transaction code is corret:

        final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class)
                                                  .child(SkeletonNetwork.class, network.getKey());
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2016-04-07 22:27:35 -0700

Veinthrough gravatar image

updated 2016-04-07 22:30:59 -0700

I solved the problem this morning.There is nothing wrong with the write-transaction operation.

Otherwise,

    private void createdNetwork(
        AsyncDataChangeEvent<InstanceIdentifier<?>, DataObject> changes) {

    for (Entry<InstanceIdentifier<?>, DataObject> newNetwork : changes.getCreatedData().entrySet()) {
        if(newNetwork.getValue() instanceof Network){
            Network network = (Network)newNetwork.getValue();
            Long num= getSkeletonNum();
            writeSkeletonNetwork( network.getUuid().getValue(), network.getName(), new Long( num+1));
            writeSkeletonNum( new Long( num+1));
        }
    }
}

    private boolean writeSkeletonNetwork( String uuid, String networkName, Long index) {
    SkeletonNetwork network= new SkeletonNetworkBuilder()
        .setUuid( uuid)
        .setName( networkName)
        .setIndex( index)
        .build();

    final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class)
                                                  .child(SkeletonNetwork.class, network.getKey());
    final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
    transaction.put( LogicalDatastoreType.CONFIGURATION, instanceIdentifier, network, true);


    CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
    try {
        future.get();
    } catch (InterruptedException | ExecutionException e) {
        LOG.warn("Transation failed ",e);
        return false;
    }
    return true;
}

    private boolean writeSkeletonNum( Long num) {
    LOG.info("[BEGIN]writeSkeletonNum, num: {}", num);

    Skeleton skeleton= new SkeletonBuilder()
        .setNum( num)
        .build();

    final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class);
    final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
    transaction.put( LogicalDatastoreType.CONFIGURATION, instanceIdentifier, skeleton, true);

    CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
    try {
        future.get();
    } catch (InterruptedException | ExecutionException e) {
        LOG.warn("Transation failed ",e);
        return false;
    }
    return true;
}

That is, every time a network was created, I will write:

1>list skeleton-network

2>leaf num

The problem is that when writing leaf num( actually write container Skeleton) , it overwrite the container Skeleton with empty list skeleton-network. To solve the problem, when writing leaf num, I should use merge instead of put.

private boolean writeSkeletonNum( Long num) {
    LOG.info("[BEGIN]writeSkeletonNum, num: {}", num);

    Skeleton skeleton= new SkeletonBuilder()
        .setNum( num)
        .build();

    final InstanceIdentifier instanceIdentifier= InstanceIdentifier.create(Skeleton.class);
    final WriteTransaction transaction = dataService.newWriteOnlyTransaction();
    transaction.merge( LogicalDatastoreType.CONFIGURATION, instanceIdentifier, skeleton, true);

    CheckedFuture<Void, TransactionCommitFailedException> future = transaction.submit();
    try {
        future.get();
    } catch (InterruptedException | ExecutionException e) {
        LOG.warn("Transation failed ",e);
        return false;
    }
    return true;
}
edit flag offensive delete publish link more
Login/Signup to Answer

Question Tools

Follow
1 follower

Stats

Asked: 2016-04-06 04:20:58 -0700

Seen: 139 times

Last updated: Apr 07 '16