cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Announcements

149
Views
1
Helpful
6
Replies
khgrant
Cisco Employee

CDB OperSubscription for pnp-state

 

Hi team,

 

 

First of all wishing you all the best in 2016.

 

 

I am reaching out again to seek help. I am trying to track changes of operational data in CDB, pnp-state, which is part of VMS code. Created NAVU subscriber as in the examples and in the User Guide. I can see that entries are there and that are gone when I delete them with "request pnp delete serial all”, but subscriber is not triggered. Here is the code that I put together.

 

 

public class PnpIpAddressCdbSub implements ApplicationComponent  {

 

    private static Logger LOGGER = Logger.getLogger(PnpIpAddressCdbSub.class);

 

 

    private NavuCdbOperSubscriber sub;

 

 

    public PnpIpAddressCdbSub() {

 

    }

 

 

    public void init() {

 

        try {

 

            sub = (NavuCdbOperSubscriber) NavuCdbSubscribers.operSubscriber("localhost",Conf.NCS_PORT);

 

            String subscriptionString = "/pnp:pnp-state/device/ip-address";

 

 

            sub.register(new NavuCdbOperDiffIterate() {

 

private final Logger SUBLOG = Logger.getLogger(PnpIpAddressCdbSub.class);

 

 

public void iterate(NavuCdbSubscriptionOperContext ctx) {

 

SUBLOG.info("FROM PNP_SUBSCRIBER!!!: " + ctx.getOperFlag() + " " + Arrays.toString(ctx.keyPath()) + " value: " + ctx.getNewValue());

 

 

switch(ctx.getOperFlag()){

 

case MOP_DELETED:

 

SUBLOG.info("FROM PNP_SUBSCRIBER!!! DELETE-Oper-FLAG!!!!");

 

 

 

 

break;

 

case MOP_CREATED:

 

SUBLOG.info("FROM PNP_SUBSCRIBER!!! MOP_CREATED-Oper-FLAG!!!!");

 

case MOP_MODIFIED: {

 

SUBLOG.info("FROM PNP_SUBSCRIBER!!! MOP_MODIFIED-Oper-FLAG!!!!");

 

break;

 

}

 

}

 

ctx.iterRecurse();

 

}

 

}, new ConfPath(subscriptionString));

 

        } catch (Exception e) {

 

            throw new RuntimeException("Fail in init", e) ;

 

        }

 

    }

 

 

    public void run() {

 

        sub.subscriberStart();

 

    }

 

 

    public void finish() {

 

        try {

 

            sub.subscriberStop();

 

            sub.executor().shutdown();

 

        } catch (Exception e) {

 

            throw new RuntimeException("Fail in finish", e) ;

 

        }

 

    }

 

}

 

 

I also tried with CDB subscriber, also without success. Any hint on what I am doing wrong is welcome!

 

 

Kind regards,

 

Bostjan

 

1 ACCEPTED SOLUTION

Accepted Solutions
khgrant
Cisco Employee

 

Hi,

 

 

Going over docs for 10th time I saw this one in the Operational data section:

 

 

* Subscription notifications are only generated if the writer obtains the “subscription lock”, by using the Cdb.startSession() method with the CdbLockType.LOCK_REQUEST flag.

 

 

If I understand this then I can do whatever, it depends on writer of operational data to do this and if it doesn’t then no notification is received.

 

 

And looking at examples I can see that test data is inserted after lock is acquired.

 

 

CdbSession sess = c.startSession(CdbDBType.CDB_OPERATIONAL,

 

  1. EnumSet.of(CdbLockType.LOCK_REQUEST, CdbLockType.LOCK_WAIT));

 

 

 

Cheers,

Bostjan

 

View solution in original post

6 REPLIES 6
khgrant
Cisco Employee

 

Hi Bostjan,

 

 

Is the subscription target defined as operational data in the YANG (config false)?

 

 

Thanks!

 

Michel

khgrant
Cisco Employee

 

Yes, I believe so, see snippet from below:

 

 

… Snip …

 

container pnp-state {

 

    config false;

 

    tailf:cdb-oper {

 

      tailf:persistent true;

 

    }

 

 

    /* CloudVPN specific */

 

    leaf mgmt-address-top {

 

      type inet:ip-address;

 

    }

 

 

    list device {

 

      key serial;

 

…snip…

 

 

BR,

 

Bostjan

 

khgrant
Cisco Employee

 

 

I recommend not using the NavuCdbSubscribers, I'm not happy at all with that library code. Not easy to fix either. Designed ages ago, in a bad manner. Should probably be deprecated.

 

 

Use the normal, regular CdbSubscriber class instead, easier and clearly better. See e.g vMS code for example usage.

 

 

If you want a Navu object, it's easier to pick up the keypath from the normal CdbSubscriber and then use the class KeyPath2NavuNode to get a Navu object (which is nice)

 

 

 

/klacke

 

khgrant
Cisco Employee

 

Hi Klacke,

 

 

Thanks for response. I was also reusing code in cloudvpn in devOperStateSub class which uses CDB subscriber without result. I just modified and subscribed it to “/“. It seems it is pulling things from config side (like pnp:pnp-subscriber) and not operational side (like pnp:pnp-state).

 

 

localadmin@ncs-vm:~/vms102/logs$ cat ncs-java-vm.log | grep PNP | grep pnp

 

<INFO> 05-Jan-2016::14:51:58.415 PnpIpAddressCdbSub$Iter (lawful-intercept:CDB PNP IP Address Changes CDB Listener)-Run-8: - Called with kp= /pnp:pnp-subscriber/device{cpe-FTX12345}/ready, OP=MOP_VALUE_SET, old_value=null, new_value=true

 

<INFO> 05-Jan-2016::14:51:58.416 PnpIpAddressCdbSub$Iter (lawful-intercept:CDB PNP IP Address Changes CDB Listener)-Run-8: - MOP_VALUE_SET EVENT Called with kp= /pnp:pnp-subscriber/device{cpe-FTX12345}/ready, OP=MOP_VALUE_SET, old_value=null, new_value=true

 

<INFO> 05-Jan-2016::14:51:58.419 PnpIpAddressCdbSub$Iter (lawful-intercept:CDB PNP IP Address Changes CDB Listener)-Run-8: - Called with kp= /pnp:pnp-subscriber/device{cpe-FTX12345}/udi, OP=MOP_VALUE_SET, old_value=null, new_value=PID:CISCO2901/K9,VID:V06,SN:FTX12345

 

<INFO> 05-Jan-2016::14:51:58.419 PnpIpAddressCdbSub$Iter (lawful-intercept:CDB PNP IP Address Changes CDB Listener)-Run-8: - MOP_VALUE_SET EVENT Called with kp= /pnp:pnp-subscriber/device{cpe-FTX12345}/udi, OP=MOP_VALUE_SET, old_value=null, new_value=PID:CISCO2901/K9,VID:V06,SN:FTX12345

 

 

BR,

 

Bostjan

 

 

public class PnpIpAddressCdbSub implements ApplicationComponent {

 

    private static Logger LOGGER = Logger.getLogger(PnpIpAddressCdbSub.class);

 

 

    @Resource(type=ResourceType.CDB, scope=Scope.INSTANCE)

 

    private Cdb cdb;

 

   

 

    private CdbSubscription sub;

 

    private int subId;

 

 

    public PnpIpAddressCdbSub() {

 

    }

 

 

    public void init() {

 

        try {

 

       

 

  1. LOGGER.warn(" Using CDB=" + cdb );

 

       

 

  1. LOGGER.warn(" Starting CDB Listener =" + this.getClass().getName());

 

 

 

       

 

sub = new CdbSubscription(cdb);

 

 

 

       

 

String subcriptionPath = "/"

 

 

 

       

 

subId = sub.subscribe(CdbSubscriptionType.SUB_OPERATIONAL,1, new Ncs(), subcriptionPath);

 

 

 

       

 

  1. sub.subscribeDone();

 

 

 

       

 

 

        } catch (Exception e) {

 

throw new RuntimeException("FAIL in init", e);

 

        }

 

    }

 

 

    public void run() {

 

        try {

 

while (true) {

 

int[] points;

 

try {

 

points = sub.read();

 

} catch (Exception e) {

 

return;

 

}

 

try {

 

sub.diffIterate(points[0], new Iter());

 

} catch (Exception ex) {

 

LOGGER.error("Exception in run : ",ex);

 

}

 

sub.sync(CdbSubscriptionSyncType.DONE_OPERATIONAL);

 

}

 

        } catch (Exception exc){

 

LOGGER.error("Exception : ", exc);

 

        }

 

    }

 

 

    public void finish() {

 

   

 

  1. LOGGER.warn(this.getClass().getName() + " in finish () =>");

 

        try {

 

// ResourceManager will close the resource (cdb) used by this

 

// instance that triggers ConfException with ErrorCode.ERR_EOF

 

// in run method

 

ResourceManager.unregisterResources(this);

 

        } catch (Exception e) {

 

throw new RuntimeException("FAIL in finish", e);

 

        }

 

        LOGGER.warn(this.getClass().getName() + " in finish () => ok");

 

    }

 

   

 

private class Iter implements CdbDiffIterate {

 

 

public DiffIterateResultFlag iterate(ConfObject[] kp, DiffIterateOperFlag op, ConfObject old_value, ConfObject new_value, Object state) {

 

try {

 

// ConfPath p = new ConfPath(kp);

 

String kpString = Conf.kpToString(kp);

 

 

 

  1. LOGGER.info("Called with kp= "+ kpString +", OP="+op+ ", old_value="+ old_value +", new_value="+ new_value);

 

// for (int i = 0; i < kp.length; i++) {

 

// LOGGER.debug("i=" + i + "; kp=" + kp[i].toString());

 

// }

 

 

 

if (op == DiffIterateOperFlag.MOP_DELETED) {

 

// LOGGER.info("Called with kp= "+ kpString +", OP="+op+ ", old_value="+ old_value +", new_value="+ new_value);

 

// for (int i = 0; i < kp.length; i++) {

 

// LOGGER.debug("i=" + i + "; kp=" + kp[i].toString());

 

// }

 

try {

 

  1. LOGGER.info("DELETE EVENT Called with kp= "+ kpString +", OP="+op+ ", old_value="+ old_value +", new_value="+ new_value);

 

// CHECK what was deleted?

 

// check if whole device was deleted

 

// remove all IP allocations

 

return DiffIterateResultFlag.ITER_RECURSE;

 

} catch (Exception e) {

 

  1. LOGGER.warn("Exception in MOP_VALUE_SET loop " + e.getMessage());

 

return DiffIterateResultFlag.ITER_CONTINUE;

 

}

 

} else if (op == DiffIterateOperFlag.MOP_VALUE_SET) {

 

try {

 

  1. LOGGER.info("MOP_VALUE_SET EVENT Called with kp= "+ kpString +", OP="+op+ ", old_value="+ old_value +", new_value="+ new_value);

 

return DiffIterateResultFlag.ITER_RECURSE;

 

} catch (Exception e) {

 

  1. LOGGER.warn(" Exception in MATCH_REST loop " + e.getMessage());

 

return DiffIterateResultFlag.ITER_CONTINUE;

 

}

 

} else {

 

return DiffIterateResultFlag.ITER_RECURSE;

 

}

 

 

 

} catch (Exception e) {

 

 

  1. LOGGER.warn(" Exception in outer loop " + e.getMessage());

 

return DiffIterateResultFlag.ITER_CONTINUE;

 

}

 

}

 

}

 

}

 

khgrant
Cisco Employee

 

Hi,

 

 

Going over docs for 10th time I saw this one in the Operational data section:

 

 

* Subscription notifications are only generated if the writer obtains the “subscription lock”, by using the Cdb.startSession() method with the CdbLockType.LOCK_REQUEST flag.

 

 

If I understand this then I can do whatever, it depends on writer of operational data to do this and if it doesn’t then no notification is received.

 

 

And looking at examples I can see that test data is inserted after lock is acquired.

 

 

CdbSession sess = c.startSession(CdbDBType.CDB_OPERATIONAL,

 

  1. EnumSet.of(CdbLockType.LOCK_REQUEST, CdbLockType.LOCK_WAIT));

 

 

 

Cheers,

Bostjan

 

khgrant
Cisco Employee

 

On 07/01/16 23:26, Bostjan Fele (bofele) wrote:

 

> Hi,

 

>

 

> Going over docs for 10th time I saw this one in the Operational data

 

> section:

 

> /* Subscription notifications are only generated if the writer obtains

 

> the “subscription lock”, by using the Cdb.startSession() method with

 

> the CdbLockType.LOCK_REQUEST flag./

 

>

 

> If I understand this then I can do whatever, it depends on writer of

 

> operational data to do this and if it doesn’t then no notification is

 

> received.

 

 

 

Correct

 

 

-klacke

 

Create
Recognize Your Peers
Content for Community-Ad