Subject: [netmod] 'Namespace Qualified' in draft-ietf-netmod-yang-json-08

From: Rob Shakir <[email-masked]>
Date: Thu, 3 Mar 2016 22:40:18 +0000

Hi NETMOD,

I am in the process of implementing draft-ietf-netmod-yang-json–08, and had some queries as to the content. Hopefully there is some misunderstanding on my part, or it helps to clean up the text for future people reviewing/implementing.

The phrase ‘namespace-qualified’ seems to have some ambiguity through the document. For example, in the case that we have two modules:

module mod-a {
    prefix "pfx-a";
    namespace "http://a.tld";
     
    container container-a {
        leaf leaf-a {
            type string;
        }
         
        leaf ref-a {
            type identityref {
                base SOME_IDENTITY;
            }
        }
    }
}

module mod-b {
    prefix "pfx-b";
    namespace "http://b.tld";
     
    container container-b {
        leaf leaf-b {
            type string;
        }
         
        leaf ref-b {
            type identityref {
                base SOME_IDENTITY;
            }
        }
    }
}
Then, AIUI, the encoding needs to specify the names of the modules for both container-a and container-b (since they sit at the root; and are in different namespaces) - so we encode these as JSON objects named mod-a:container-a and mod-b:container-b as per Section 4 of the document.

In this case, we never use the actual namespace (i.e., http://a.tld and http://b.tld) so calling it ‘namespace qualified’ appears ambiguous. Should it be simply referred to as ‘module-qualified’?

Secondarily, the example in Section 6.8 does not actually use the name of the module, it rather uses the prefix (if for the interface-type leaf). This doesn’t seem to be explained anywhere within the text. Is this a mistake?

If it’s not (and one could encode container-a and container-b above as pfx-a:container-a and pfx-b:container-b), then how do we deal with this case:

module a {
        import b { prefix "c"; }
         
        leaf id {
            type identityref {
                base "c:SOME_IDENTITY";
            }
        }
}

module b {
    ...
    prefix "b";
    ...
}
when we encode, if we’re just given a value, do we add the prefix that a uses to import b, or the prefix that b defines itself? (If the prefix is used for identityref values, then the same question exists for those values - today, one must track all prefixes that are related to a certain identity value based on different imports, such that one does not incorrectly reject some prefix:identity statement that was valid).

It seems to me that using the module name consistently throughout the encoding is preferable, since this cannot be different in a number of places; and isn’t as long as the namespace value to make readability worse.

I also didn’t understand why an identityref value encodes the namespace in the actual value? It seems like the “base” of the identityref should qualify all possible values here; with the only case that we would ever need this is one where we have:

leaf some-reference {
    type union {
        type identityref {
            base "a";
        }
        type identityref {
            base "b";
        }
    }
}
And a and b both define a value with the same name (where one needs the prefix to be able to refer to the b version).

Thanks,
r.

---

From: Kent Watsen <[email-masked]>
Date: Thu, 3 Mar 2016 23:32:37 +0000

> In this case, we never use the actual namespace (i.e., http://a.tld and http://b.tld) so calling it ‘namespace qualified’ appears ambiguous. Should it be simply referred to as ‘module-qualified’?

It is a bit of a misnomer, and perhaps could be improved, but Section 4 defines “namespace-qualified” as “name of module”:

   o  namespace-qualified - the data node identifier is prefixed with
      the name of the module in which the data node is defined,
      separated from the data node identifier by the colon character
      (":”).

> Secondarily, the example in Section 6.8 does not actually use the name of the module, it rather uses the prefix (if for the interface-type leaf). This doesn’t seem to be explained anywhere within t…

The module is YANG, and in YANG the prefix is used, so “if” is correct.   Below the example module is a JSON snippet, where you’ll find a module’s full name qualifying the identity.

> If it’s not (and one could encode container-a and container-b above as pfx-a:container-a and pfx-b:container-b), then how do we deal with this case: <SNIP/>

I think you’re mixing things up, JSON encoding only uses module-names.

> It seems to me that using the module name consistently throughout the encoding is preferable, since this cannot be different in a number of places; and isn’t as long as the namespace value to make…

Indeed.

> I also didn’t understand why an identityref value encodes the namespace in the actual value?

It can also be simple form (w/o namespace) if the identity is defined in the same module...

> It seems like the “base” of the identityref should qualify all possible values here;

You mean that the namespace is implicitly defined in the YANG, so having it also in the JSON is redundant?

> with the only case that we would ever need this is one where we have:

leaf some-reference {
    type union {
        type identityref {
            base "a";
        }
        type identityref {
            base "b";
        }
    }
}

> And a and b both define a value with the same name (where one needs the prefix to be able to refer to the b version).

Small nit, but I think this might be better represented using more than one “base” statement in the identityref:

leaf some-reference {
    type identityref {
        base "a";
        base "b";
    }
}

Regardless, my only thought is that it is for consistency.   I’m sure others will have a better answer.

K.

---

From: Rob Shakir <[email-masked]>
Date: Thu, 3 Mar 2016 23:47:55 +0000

Hi Kent,

Thanks for the response!

   o  namespace-qualified - the data node identifier is prefixed with
      the name of the module in which the data node is defined,
      separated from the data node identifier by the colon character
      (":”).
Thanks. Is there a reason to call this namespace, when we also have a namespace statement in the module? It seems to present an opportunity to cause confusion with little benefit?

The module is YANG, and in YANG the prefix is used, so “if” is correct.   Below the example module is a JSON snippet, where you’ll find a module’s full name qualifying the identity.
Ah, sorry — you’re right.

It can also be simple form (w/o namespace) if the identity is defined in the same module...
Agreed, I’m more wondering why *ever* carry it.

You mean that the namespace is implicitly defined in the YANG, so having it also in the JSON is redundant?
Yes. Any identity value that extends that base must be unique AIUI, so each of those values then defines its namespace. Why do we carry it in the JSON?

Thanks again.

r.

---

From: Per Hedeland <[email-masked]>
Date: Fri, 4 Mar 2016 08:19:17 +0100

> Yes. Any identity value that extends that base must be unique AIUI, so each of those values then defines its namespace. Why do we carry it in the JSON?

The identity values must indeed be unique - and that's precisely why
they need module/namespace qualification. In the example below, a:x and
b:x are valid and different values for the leaf y. Obviously a more
realistic example would have two modules defining "conflicting"
identities with a base defined in a third module - i.e. this logic makes
it possible for "independent parties" to define unique identities with a
common base, without the need for having a "global registry".

--Per Hedeland

module a {
  namespace urn:a;
  prefix a;

  identity id;

  identity x {
    base id;
  }
}

module b {
  namespace urn:b;
  prefix b;

  import a {
    prefix a;
  }

  identity x {
    base a:id;
  }

  leaf y {
    type identityref {
      base a:id;
    }
  }
}

---

From: Ladislav Lhotka <[email-masked]>
Date: Fri, 04 Mar 2016 13:05:12 +0100

Hi Rob,

Rob Shakir <[email-masked]> writes:

> Then, AIUI, the encoding needs to specify the names of the modules for
>             both container-a and container-b (since they sit at the
>             root; and are in different namespaces) - so we encode
>             these as JSON objects named mod-a:container-a and
>             mod-b:container-b as per Section 4 of the document.

Correct.

>
> In this case, we never use the actual namespace (i.e., http://a.tld
> and http://b.tld) so calling it ‘namespace qualified’ appears
> ambiguous. Should it be simply referred to as ‘module-qualified’?

Namespaces (= sets of names) as defined by YANG are
encoding-independent. However, XML and JSON use different namespace
identifiers. XML uses naturally the mechanism of [XML-NAMES], i.e. namespace URIs
and references via declared prefixes. JSON in general doesn't support
namespaced member names, but we could conveniently use the module name
as the namespace identifier. So this is what Sec. 4 defines:

   The name of a module determines the namespace of all data node names
   defined in that module.  If a data node is defined in a submodule,
   then the namespace-qualified member name uses the name of the main
   module to which the submodule belongs.

This is then later extended to other named entities such as identities.
>
> Secondarily, the example in Section 6.8 does not actually use the name
> of the module, it rather uses the prefix (if for the interface-type
> leaf). This doesn’t seem to be explained anywhere within the text. Is
> this a mistake?

No, it's correct. YANG adopted the XML namespace rules, so declared
prefixes are used in YANG modules. The JSON-encoded name of the identity
uses the rules of the yang-json document, i.e. module name as the
namespace identifier. 

> It seems to me that using the module name consistently throughout the
> encoding is preferable, since this cannot be different in a number of
> places; and isn’t as long as the namespace value to make readability
> worse.

Module name is used consistently in JSON encoding, but we have to use
YANG rules when dealing with YANG modules.

It is somewhat confusing but I believe this is the best solution we
could come up with.  

>
> I also didn’t understand why an identityref value encodes the
> namespace in the actual value? It seems like the “base” of the
> identityref should qualify all possible values here; with the only
> case that we would ever need this is one where we have:

I think Per explained this part nicely.

Thanks, Lada

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

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

---

From: Rob Shakir <[email-masked]>
Date: Fri, 11 Mar 2016 16:40:01 -0700

Thanks Lada and others for the responses here. Much clearer to me.

r.

On 4 March, 2016 at 5:05:03 AM, Ladislav Lhotka ([email-masked]) wrote:

Hi Rob,  

Correct.  

Thanks, Lada