[NETCONF-70] Support multiple Yang model revisions for mounted nodes Created: 24/Sep/15  Updated: 13/Aug/19

Status: Confirmed
Project: netconf
Component/s: netconf
Affects Version/s: None
Fix Version/s: None

Type: Improvement
Reporter: Wojciech Dec Assignee: Unassigned
Resolution: Unresolved Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Operating System: All
Platform: All


Issue Links:
Blocks
is blocked by MDSAL-237 Milestone: Implement Binding Specific... Resolved

 Description   

Current code supports only one version of a given Yang model mounted from remote devices. The presence of another same model revision breaks things.
Discussed at 2015 July ODL Summit...



 Comments   
Comment by Wojciech Dec [ 25/Sep/15 ]

Clarifying: Issue is seen when same model, but with different revisions is mounted from two or more netconf devices.

Although logs are from Helium, issue is also there in Lithium:

2015-07-24 20:50:06,501 | ERROR | lt-dispatcher-35 | DataChangeListener | 161 - org.opendaylight.controller.sal-distributed-datastore - 1.1.1.Helium-SR1-00004_1-SNAPSHOT | Error notifying listener org.opendaylight.controller.listeners.impl.MyAppl
java.lang.IllegalArgumentException: Failed to normalize path /(http://www.cisco.com/yang/cisco-vpp?revision=2015-06-09)vpp/bridge-domains/bridge-domain[

{(http://www.cisco.com/yang/cisco-vpp?revision=2015-06-09)name=11f1a31a-118c-4154-a7a7-45fa98f5aaa4}

]
at org.opendaylight.controller.md.sal.common.impl.util.compat.DataNormalizer.toNormalized(DataNormalizer.java:69)[82:org.opendaylight.controller.sal-common-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleTransaction.readConfigurationData(BackwardsCompatibleTransaction.java:95)[134:org.opendaylight.controller.sal-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.md.sal.dom.broker.impl.compat.BackwardsCompatibleDataBroker.readConfigurationData(BackwardsCompatibleDataBroker.java:48)[134:org.opendaylight.controller.sal-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.sal.dom.broker.BackwardsCompatibleMountPoint.readConfigurationData(BackwardsCompatibleMountPoint.java:181)[134:org.opendaylight.controller.sal-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector.readConfigurationData(BindingIndependentConnector.java:118)[137:org.opendaylight.controller.sal-binding-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.sal.binding.impl.connect.dom.BindingIndependentConnector.readConfigurationData(BindingIndependentConnector.java:43)[137:org.opendaylight.controller.sal-binding-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.sal.binding.impl.DataBrokerImpl$DelegatingDataReadRouter.readConfigurationData(DataBrokerImpl.java:132)[137:org.opendaylight.controller.sal-binding-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.sal.binding.impl.DataBrokerImpl$DelegatingDataReadRouter.readConfigurationData(DataBrokerImpl.java:125)[137:org.opendaylight.controller.sal-binding-broker-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.md.sal.common.impl.service.AbstractDataBroker.readConfigurationData(AbstractDataBroker.java:214)[82:org.opendaylight.controller.sal-common-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.md.sal.common.impl.service.AbstractDataTransaction.readConfigurationData(AbstractDataTransaction.java:71)[82:org.opendaylight.controller.sal-common-impl:1.1.1.Helium-SR1-00004_1-SNAPSHOT]
at org.opendaylight.controller.store.VHostUserToInterfaceBuilder.createVHostUserClientInterface(VHostUserToInterfaceBuilder.java:130)[233:org.opendaylight.controller.neutronvpp-provider:1.1.1.00004_1-SNAPSHOT]
at org.opendaylight.controller.listeners.impl.NeutronPortListenerImpl.add(NeutronPortListenerImpl.java:278)[233:org.opendaylight.controller.neutronvpp-provider:1.1.1.00004_1-SNAPSHOT]
at org.opendaylight.controller.listeners.impl.NeutronPortListenerImpl.add(NeutronPortListenerImpl.java:55)[233:org.opendaylight.controller.neutronvpp-provider:1.1.1.00004_1-SNAPSHOT]

Comment by Wojciech Dec [ 03/Feb/16 ]

Perhaps I'm missing something here, but how does 4577 solve the problem described here?
Having a separate model cache per device, and a manually configured one at that, doesn't seem to apply here.

The issue is that the binding aware code "binds" to the Yang model derived version, and if the device doesn't have that version, it fails with the error below. Given that the Yang RFC mandates that yang models be backwards compatible, this is broken behavior.

Comment by Wojciech Dec [ 25/May/16 ]

Re-opening: The 4577 fix provides an impractical workaround. It is not realistic to specify, mount and maintain a separate cache for each device.
Aside from the obvious kludginess, the there is opaqueness in the solution (who would ever know about this setting?)
Furthermore, one obvious problem is that devices do get upgraded after being in production and it is not at all intuitive that the cache on ODL needs to be "cleaned", etc.

Comment by Abbas P Pareedkunju [ 31/May/16 ]

Hi,

On the latest build it seems working fine.

opendaylight-user@root>shell:exec curl -u'admin:admin' -X PATCH -H "Content-Type:application/yang.patch+json" -d '{"ietf-restconf:yang-patch":{"patch-id":"0","edit":[{"edit-id":"0","operation":"replace","target":"/","value":{"car:cars":{"car-entry":[

{"id":"0"}

]}}}]}' localhost:8080/restconf/config/car:cars ;echo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 152 0 0 100 152 0 542 -::- -::- -::- 540

opendaylight-user@root>

Can this be closed?

Thanks,
Abbas

Comment by Wojciech Dec [ 31/May/16 ]

(In reply to Abbas P Pareedkunju from comment #5)
> Hi,
>
> On the latest build it seems working fine.
>
> opendaylight-user@root>shell:exec curl -u'admin:admin' -X PATCH -H
> "Content-Type:application/yang.patch+json" -d
> '{"ietf-restconf:yang-patch":{"patch-id":"0","edit":[{"edit-id":"0",
> "operation":"replace","target":"/","value":{"car:cars":{"car-entry":[

{"id": > "0"}

]}}}]}' localhost:8080/restconf/config/car:cars ;echo
> % Total % Received % Xferd Average Speed Time Time Time
> Current
> Dload Upload Total Spent Left Speed
> 100 152 0 0 100 152 0 542 -::- -::- -::-
> 540
>
> opendaylight-user@root>
>
>
> Can this be closed?
>
> Thanks,
> Abbas

Working fine in what way?
As per my comments, it's totally impractical to mount devices with their own schema store (which is the workaround).

Comment by Abbas P Pareedkunju [ 31/May/16 ]

Hi,

On the latest build it seems working fine.

opendaylight-user@root>shell:exec curl -u'admin:admin' -X PATCH -H "Content-Type:application/yang.patch+json" -d '{"ietf-restconf:yang-patch":{"patch-id":"0","edit":[{"edit-id":"0","operation":"replace","target":"/","value":{"car:cars":{"car-entry":[

{"id":"0"}

]}}}]}' localhost:8080/restconf/config/car:cars ;echo
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 152 0 0 100 152 0 542 -::- -::- -::- 540

opendaylight-user@root>

Can this be closed?

Thanks,
Abbas

Comment by Abbas P Pareedkunju [ 31/May/16 ]

Missed your last comment. And due to the slowness in the system, my comment has been posted twice. Apologies !

Comment by Giles Heron [ 31/May/16 ]

Hi Woj,

this isn't meant to be one model per device. rather it's one model per device software revision where two revisions expose different versions of the same model but with the same revision date.

unless I've mis-remembered it

Giles

Comment by Wojciech Dec [ 31/May/16 ]

I don't quite follow "two revisions expose different versions of the same model but with the same revision date"; seems like a direct violation of the Yang spec.

In any case, the "fix" that led to the closure of this defect requires that when mounting a device, a separate directory is specified for that device's model cache. That a) is totally opaque to the user (what operator would ever remember) b) fails as soon as the mounted device gets upgraded to a new model (coz the cache still stays).
Moreover, the fix actually didn't work in the VPP case (I opened a separate bug with the issue I saw)

So, what I'm arguing for here is that a cleaner solution be devised.
If we need to store each device's models in a separate cache dir, then at least let's hide it from the user and clean it up on disconnect, etc. That's just an idea.

Comment by Giles Heron [ 31/May/16 ]

So the model here (IIRC) is you specify a directory to store the cached schemas in. So there's nothing to stop you using the same directory for multiple devices. So while you specify the cache dir per device there isn't generally one cache dir per device.

And re violations of the YANG spec I think it was issues with auto-generated YANG models that prompted this.

There may also be cases where you need to hand-edit a specific rev of a YANG model for some devices but not others (e.g. incorrect implementation on the device OS).

Remember - not all devices do everything correctly (sure, I know I'm teaching you to suck eggs here).

Comment by Ryan Goulding [ 31/May/16 ]

"So there's nothing to stop you using the same directory for multiple devices. So while you specify the cache dir per device there isn't generally one cache dir per device."

Correct; this is how I designed this; it is a workaround to deal with the fact that YANG revisionless imports are broken in ODL. Generally, we set up a cache for a specific version of router and make the changes locally there (if necessary, sometimes just honoring the device manufacturers yang works).

In fact, without specifying a specific revision for import, the revision that is resolved is non-deterministic (hence why you will see hard-coded assumptions in the standard files utilized by ODL like https://git.opendaylight.org/gerrit/#/c/21049/).

Initially Tony was working on a solution to correctly handle revisionless imports through programatic resolution, but I believe he punted this since it could be solved through the binding v2 specification work.

While NETCONF-96 solution was not perfect, it satisfied the use case I required at the time; if it isn't a perfect fit for you I can certainly understand that. This was done in the 11th hour of the Beryllium release to ensure that devices could at least be mounted in Beryllium.

Please feel free to work on a different approach; I'd be interested to see how others solve it.

Comment by Wojciech Dec [ 31/May/16 ]

We may be talking about overlapping things.

Adding a cache store directory that's a parameter in a mount point isn't cool. Who on earth will ever know about that parameter, remember to use it, when to change it, etc, when to clean the cache, besides perhaps the people here?
It's the hallmark of a super-nerd knob, for what is in essence a fundamental non-nerd requirement of the original bug: Support devices with multiple "same name, different revision" yang models.

As far as the Yang spec is concerned, there really is only one correct answer here: The spec, which says that revisions have to be a) renumbered b) backwards compatible. It is a rat hole to engineer for non-yang spec compliant cases.
If the fix here dealt with the "revised model, but not up-versioned case", then unfortunately it seems to be such a rat-hole case.

Besides, the fundamental issue remains: A BA app built against device model rev X does not communicate properly with a mixed pool of devices running models X and Y.

Comment by Tomas Cere [ 31/May/16 ]

(In reply to Wojciech Dec from comment #13)
> We may be talking about overlapping things.
>
> Adding a cache store directory that's a parameter in a mount point isn't
> cool. Who on earth will ever know about that parameter, remember to use it,
> when to change it, etc, when to clean the cache, besides perhaps the people
> here?

That's why there's documentation for this feature on the wiki, right?

That's why there's documentation for it on the wiki, right?
(In reply to Wojciech Dec from comment #10)

> So, what I'm arguing for here is that a cleaner solution be devised.
> If we need to store each device's models in a separate cache dir, then at
> least let's hide it from the user and clean it up on disconnect, etc. That's
> just an idea.

Seems like you don't really want to cache the models.

As for the BA app problem when it can't be used for multiple revisions of the same model the v2 binding spec should fix that but that's still some time away.

Comment by Wojciech Dec [ 31/May/16 ]

(In reply to Tomas Cere from comment #14)
> (In reply to Wojciech Dec from comment #13)
> > We may be talking about overlapping things.
> >
> > Adding a cache store directory that's a parameter in a mount point isn't
> > cool. Who on earth will ever know about that parameter, remember to use it,
> > when to change it, etc, when to clean the cache, besides perhaps the people
> > here?
>
> That's why there's documentation for this feature on the wiki, right?

"we have a wiki" is fine for non essential nerd-knobs.
Nerd-knobs, even if documented ones, for what is essential system behavior are not a good idea & never have been - the system should behave like that by default.

>
> That's why there's documentation for it on the wiki, right?
> (In reply to Wojciech Dec from comment #10)
>
> > So, what I'm arguing for here is that a cleaner solution be devised.
> > If we need to store each device's models in a separate cache dir, then at
> > least let's hide it from the user and clean it up on disconnect, etc. That's
> > just an idea.
>
> Seems like you don't really want to cache the models.

I don't see where I said that, but anyway...

>
> As for the BA app problem when it can't be used for multiple revisions of
> the same model the v2 binding spec should fix that but that's still some
> time away.

To summarize:

  • The issue raised by this bug, support BA app + devices with multiple model versions is fundamental system behavior.
  • The issue raised by this bug has not been fixed. Any fix for it must IMO not involve special "nerd knobs", i.e. it should be default.
  • The fix that has been attributed to this bug is for some other problem (revised models without version changes). IMO this other problem does not appear to be as fundamental, and a nerd-knob may be adequate.
Comment by Tomas Cere [ 31/May/16 ]

(In reply to Wojciech Dec from comment #15)
> I don't see where I said that, but anyway...

Well cleaning up the cache(== delete) after disconnect defeats the entire purpose(which is to avoid redownloading of schemas already present in the system) of the cache doesn't it?

You don't want to use as you put it "nerd-knobs", that's fine, but this issue is not something we can fix on netconf level as this has to do with binding generation. The fix by Ryan can be of use to some people that encounter similar issues, or are willing to workaround the issue and should be mentioned here.

Comment by Wojciech Dec [ 31/May/16 ]

(In reply to Tomas Cere from comment #16)
> (In reply to Wojciech Dec from comment #15)
> > I don't see where I said that, but anyway...
>
> Well cleaning up the cache(== delete) after disconnect defeats the entire
> purpose(which is to avoid redownloading of schemas already present in the
> system) of the cache doesn't it?

A cache is by definition time-bound. Otherwise it becomes a rubbish dump. Anyway, the problem I opened is different...
>
> You don't want to use as you put it "nerd-knobs", that's fine, but this
> issue is not something we can fix on netconf level as this has to do with
> binding generation. The fix by Ryan can be of use to some people that
> encounter similar issues, or are willing to workaround the issue and should
> be mentioned here.

Sure, Ryan's fix can be useful to whoever has the problem, but mentioning it in the context of "it fixes" the issue raised by this bug is simply not true. If the component is wrong, let's change that.

Comment by Tomas Cere [ 31/May/16 ]

Added the binding spec dependency which should be enough

Generated at Wed Feb 07 20:14:06 UTC 2024 using Jira 8.20.10#820010-sha1:ace47f9899e9ee25d7157d59aa17ab06aee30d3d.