Subject: [netmod] comments on draft-lhotka-yang-json-00

From: Andy Bierman <[email-masked]>
Date: Sat, 28 Apr 2012 06:31:39 -0700

Hi,

I am trying to use this draft in some prototype work.
I really like it, except for sec. 3.1.
It states that the module:local-name variant MUST be
used for top-level and any descendants from external augment
(namespace change).

IMO this is way too restrictive and not user friendly.
Most YANG implementers try really hard not to have
any configuration nodes with the same local name.
It's not user-friendly since the CLI often
shares the YANG model, and users don't like typing long module names.

The server MUST require the module:local-name variant whenever
there are sibling nodes with different expanded names but the same
local names.  If there is no local name collision, the module name
can be left out.

IMO:
  * The server MUST accept the module:local-name form whenever it is used.
  * The client MAY use the procedures in sec. 3.1

It is OK to assume the client knows the set of active modules
on the server.  An app can fill in the module and a CLI can prompt
if there is a local-name conflict.  If the client wants to be
cautious and guard against future modules adding local-name
collisions, they can follow the advice in sec. 3.1.
But clients should not be forced to do that.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Sun, 29 Apr 2012 18:14:40 +0200

> I am trying to use this draft in some prototype work.

Great!

> local names.  If there is no local name collision, the module name

My very first version of the draft had this rule, but after a discussion with Martin I changed my mind. The advantage of the current system is that the namespace of every node, hence the YANG module where it is defined, is immediately visible from the instance document. I agree with you that in most cases explicit namespaces won't be necessary at all so users needn't bother about them.

> * The client MAY use the procedures in sec. 3.1

 * There form module:local-name MUST be used whenever there is a collision in local-name.

These three rules make sense to me, too.
 
> But clients should not be forced to do that.

The draft essentially addresses the form of JSON documents that would be exchanged between the server and the client, in the same way as the "XML Mapping Rules" sections in 6020 address XML documents. I believe at this stage the namespaces must already be uniquely resolvable.

Any opinions?

Lada

> 
> Andy
> 
> _______________________________________________
> netmod mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/netmod

--
Ladislav Lhotka, CZ.NIC Labs
PGP Key ID: E74E8C0C

---

From: Andy Bierman <[email-masked]>
Date: Sun, 29 Apr 2012 09:35:15 -0700

> My very first version of the draft had this rule, but after a discussion with Martin I changed my mind. The advantage of the current system is that the namespace of every node, hence the YANG modul…

IMO, the probability of local name collisions is < .0001

I don't think users want an educational experience to be reminded
of the YANG module name associated with the configuration data.

If the server can determine the expanded name for the given local name part
(because there are no siblings with duplicate local names) then forcing
the server to return an error anyway does not follow the Postel Principle.

Andy

---

From: Martin Bjorklund <[email-masked]>
Date: Sun, 29 Apr 2012 22:14:24 +0200 (CEST)

Hi,

Ladislav Lhotka <[email-masked]> wrote:
> My very first version of the draft had this rule, but after a discussion with
> Martin I changed my mind. The advantage of the current system is that the
> namespace of every node, hence the YANG module where it is defined, is
> immediately visible from the instance document. I agree with you that in most
> cases explicit namespaces won't be necessary at all so users needn't bother
> about them.
> 
> > 
> > IMO:
>  * There form module:local-name MUST be used whenever there is a collision in
>  * local-name.
> 

The problem with this approach is that unless the client has parsed and
interpreted all modules a server implement, it has to use the
module:local-name on *all* nodes, if it wants to be certain to avoid
errors.  This isn't very user friendly.

When the module:local-name syntax only is used on augmenting nodes (as
it is in the current draft), the client adds the module name only when
crossing modules.

It might be ok to let the client skip the module name if there is no
collision on the server though...  But consider this case:

The server implements:

  module a {
    ...
    container top;
  }

  module b {
    ...
    augament /a:top {
      leaf foo { type int32; }
    }
  }

The client sends: 

    "top" : {
       "foo": 42
    }

and this works.  Now, the server upgrades module a to this:

  module a {
    ...
    container top {
      leaf foo { type int32; }
    }
  }

The client's request still works, but sets another leaf.  Not good.

/martin

---

From: Andy Bierman <[email-masked]>
Date: Sun, 29 Apr 2012 14:14:50 -0700

On 04/29/2012 01:14 PM, Martin Bjorklund wrote:
> Hi,
>
> Ladislav Lhotka<[email-masked]>  wrote:
>>

The client MAY choose to use the module name all the time if it wants.
It doesn't need to do that since a child node without a module name will
be interpreted as the same module as the parent.  There is no
ambiguity at all, if the procedure in 3.1 is followed.

But it should be up to the client to decide how strict to be.
The server should accept liberal input.  Nobody actually uses
module:local-name in the real world.  Mandating that format
to solve a problem that doesn't actually occur in real deployment
seems more unfriendly to users.

> The client's request still works, but sets another leaf.  Not good.

Not what happens.
The server will reject the request because now it has multiple
siblings that match the same local name, with no module specified.
That is an error -- not first one wins.

The client MAY choose to send, or even SHOULD send, but not MUST send:

       "a:top" : {
          "b:foo": 42
       }

Then it will guard against this hypothetical problem.
Vendors don't actually do augment in this fashion.  The vendors I have talked
to would make sure not to augment a module with duplicate node names.

BTW, the JSON encoding is wrong.
All the XML <--> converters I found do this:

XML:

<top>
   <foo>42</foo>
</top>

JSON:

   {
      "top" : {
         "foo" : "42"
      }
   }

Otherwise the reverse translation is lost.

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 30 Apr 2012 07:11:06 +0200

> That is an error -- not first one wins.

Right, rule #3 above makes the client input with unqualified "foo" invalid.

> All the XML <--> converters I found do this:

Yes, according to the ABNF in RFC 4627, JSON-text starts with either "{" (object) or "[" (array). The draft should also state that an XML document translates to a JSON object.

Lada

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 30 Apr 2012 08:28:58 +0200 (CEST)

Andy Bierman <[email-masked]> wrote:
> >>   * There form module:local-name MUST be used whenever there is a
> >>   * collision in
> >>   * local-name.
> >>

I think you misinterpreted the context in which I made this claim.
There are three alterative encodings on the table:
 
 1.  The enconding described in the draft.
     (required "module:" on module crossing)
    
 2.  Your proposed lax encoding.
     (require "module:" if there is a collision - even if the child is
     in the same module as parent)

 3.  The encoding described in the draft + the client MAY skip
     module-name.

Let me re-state what I wrote earlier.

With (2), the client has to use the module:local-name on *all* nodes,
if it wants to be certain to avoid errors.  This isn't very user
friendly.

With (3), the scenario I described above could happen.

> to would make sure not to augment a module with duplicate node names.

One sceanario is that a vendor adds node "foo", and later this node
"foo" gets picked by a standard module.  Then this happens.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 30 Apr 2012 08:56:22 +0200

> if it wants to be certain to avoid errors.  This isn't very user

Why? Which errors? The client knows the data model and can therefore determine whether there is a collision in local names or not.

> With (3), the scenario I described above could happen.

In your scenario, after the server upgrade the client input is no more valid. The client has to take into account the new data model, realize the collision in "foo", and use the prefix:

{
  "top" : {
    "b:foo" : 42
  }
} 

> "foo" gets picked by a standard module.  Then this happens.

If the vendor upgrades to the new revision of the standard module, it should also remove its proprietary "foo".

I think in practice the data models cannot be a haphazard collection of modules and will be quite carefully selected and controlled.

Lada

---

From: Martin Bjorklund <[email-masked]>
Date: Mon, 30 Apr 2012 09:08:26 +0200 (CEST)

Ladislav Lhotka <[email-masked]> wrote:
> Why? Which errors? The client knows the data model and can therefore
> determine whether there is a collision in local names or not.

This is what I originally wrote:

  The problem with this approach is that unless the client has parsed
  and interpreted all modules a server implement, it has to use the
  module:local-name on *all* nodes, if it wants to be certain to avoid
  errors.  This isn't very user friendly.

The error I refer to is the collision error.  Suppose you write a
client for a certain data model A:

  { 
     "top": {
        "foo": 42
     }
  }

The client checks that the server implements A, and sends this.  The
problem with encoding scheme (2) is that if the server also implements
B, the client will get a collision error with this request.  Thus, the
client must understand all modules a server implements.

The underlying assumption (of doing a REST interface) is that it is
supposed to be dead-simple.  Requiring the client to understand *all*
data models implemented by a server is not.

> In your scenario, after the server upgrade the client input is no more
> valid. The client has to take into account the new data model, realize
> the collision in "foo", and use the prefix:
> 
> {
>   "top" : {
>     "b:foo" : 42
>   }
> } 

Exactly.  Not user-friendly for the client.

> If the vendor upgrades to the new revision of the standard module, it
> should also remove its proprietary "foo".

Sure, but there will be old servers and old clients out there for some
time, unless you require all implementations to upgrade
simultaneously...

> I think in practice the data models cannot be a haphazard collection
> of modules and will be quite carefully selected and controlled.

Sure.

/martin

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 30 Apr 2012 09:45:35 +0200

> data models implemented by a server is not.

Well, if we regard the data model as a contract, we'd better assume that both parties understand it (including the fine print:-). Module B can introduce other things that break old client code.

It would actually be nice to have rules in YANG that prevent module B from having backward-incompatible side effects on module A, but it is not the case. The rule stating that "augment" cannot define mandatory nodes goes in that direction but it is not enough: e.g., B can define new "must" constraints affecting A, or even deviations.

Lada

---

From: Andy Bierman <[email-masked]>
Date: Mon, 30 Apr 2012 06:56:51 -0700

>>>>   * There form module:local-name MUST be used whenever there is a collision in

This is the approach I prefer.

...

Andy

---

From: Ladislav Lhotka <[email-masked]>
Date: Mon, 30 Apr 2012 17:05:37 +0200

> This is the approach I prefer.

Yup, it is the most flexible option. Server and application developers may choose to use the module prefixes if and where they want to, but with sane data models it is quite likely that explicit namespace identifiers won't be needed at all, which is IMO a great virtue.

Lada