<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Dec 6, 2013 at 4:52 PM, Kevin Harwell <span dir="ltr"><<a href="mailto:kharwell@digium.com" target="_blank" onclick="window.open('https://mail.google.com/mail/?view=cm&tf=1&to=kharwell@digium.com&cc=&bcc=&su=&body=','_blank','location=yes,menubar=yes,resizable=yes,width=800,height=600');return false;">kharwell@digium.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">On Fri, 2013-12-06 at 14:21 -0700, George Joseph wrote:<br>

> This continues a conversation kharwell, mjordan and I were having on<br>
> irc this morning concerning the implementation of the cli output<br>
> formatting.<br>
><br>
><br>
> Basically, I'm thinking that while we should absolutely re-use the<br>
> underlying plumbing ( we don't need 2 versions of<br>
> ast_sip_for_each_contact, for instance), the CLI and AMI are different<br>
> enough that we shouldn't try to re-use the formatter registration and<br>
> execution plumbing.  The same pattern maybe, but not share the<br>
> structure definitions, list of formatters, etc.<br>
><br>
><br>
> The pjsip/sorcery implementation is obviously a relational/oo model.<br>
>  Endpoint, Aor, Auth, etc are all first class objects with foreign<br>
> keys/references to each other.  Typically an API in this environment<br>
> doesn't de-normalize/de-reference/re-hydrate the references to other<br>
> objects.  In REST terms, if you do a GET on an endpoint, the response<br>
> may contain a collection of aor ids but you shouldn't be getting the<br>
> detail for each aor in an endpoint response.  If you want the details,<br>
> you do a GET on each aor.   A CLI implementation is much different.<br>
>  If a human, particularly this human, has to do a 'pjsip show<br>
> endpoint', write down the list of aors, then do a 'pjsip show aor' on<br>
> each, the response from the human would be quite vivid.  Also, aors<br>
> being first-class objects in their own right can be listed and details<br>
> shown independently of any other object.<br>
><br>
><br>
> So, here's what I'm suggesting...<br>
> Two formatter registries, one for CLI and one for AMI.  I haven't been<br>
> following the ARI discussions at all so maybe there's a third?<br>
> Anyway, this way the CLI or AMI command processors don't have to<br>
> filter out the ones they don't need and we don't unnecessarily lock<br>
> the CLI and AMI implementations together.  Each object implementation<br>
> would register a formatter for each mechanism which would take care of<br>
> anything specific to that mechanism.  For the CLI for instance, the<br>
> formatter would provide a human consumable summary or detail depending<br>
> on a flag passed to it.<br>
<br>
I think the models (summary/detail/some other view) are the same in all<br>
scenarios, but we are just approaching it from two different<br>
implementation perspectives.  The way the code is currently structured<br>
removes the need for the flag, so there is no need for an if/switch<br>
statement.<br></blockquote><div><br></div><div>For the CLI, the only difference between summary and detail is that the detail flag causes the sorcery name/value pairs to be dumped in a tabular format. </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">


<br>
> I already have a context object that maintains formatting flags,<br>
> summary statistics, etc. that would be much different for AMI or ARI.<br>
<br>
Yes, the output between all could be quite different.  For each object<br>
type there are a set of formatters, serializers, printers, or whatever<br>
we want to call them (for instance, to_string, to_json, to_xml, etc...).<br>
<br>
Typically when you want to print out a non-primitive property then it<br>
makes sense to call its formatter.  However, in our case we have several<br>
different views depending on the output type, so we have to have custom<br>
formatters for each view.<br>
<br>
Currently we can register these custom formatters with the master object<br>
and when it gets formatted the associated object's custom formatter gets<br>
called (no need for a flag specifying the formatting view).<br>
<br>
Although now that I think about it having that flag would allow you to<br>
register multiple custom views for a [sub]type.  That may actually be<br>
needed in some cases some I would be fine with adding that in.<br>
<br>
As far as breaking it out into separate lists (endpoints_to_json list,<br>
endpoints_to_cli list, aors_to_json, etc...) I don't see a need for it.<br>
It will add multiple/extra register functions and more looping when<br>
formatting/outputting.  For instance, currently you register the<br>
[sub]type format function with a particular object type.  If I am<br>
thinking about it correctly with separate lists you would essentially<br>
register the list with an object type and loop over the lists of lists<br>
to output the [sub]type custom view.<br>
<br></blockquote><div>Not suggesting separate lists for each object type.  What I'm really suggesting is a hashtable for each of the output mechanisms.  One for CLI, one for AMI, etc.  Each object (endpoint, aor, auth, etc) registers a single cli formatter, single ami formatter, etc.  The key for the hastables is the sorcery object type.  So, for example, if the CLI command processor had an aor object it would do a simple table lookup in the CLI formatter registry for "aor" to get the aor formatter.  In fact, it doesn't even have to know it's an aor because it can just lookup by details->object->type.</div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><br>
> As a side note...  most of the cli stuff is in<br>
> pjsip_configuration..c.  I'm thinking of moving the common cli stuff<br>
> into a new pjsip_cli.c and the formatters into their respective<br>
> objects and since pjsip_configuration.c really only manages endpoint,<br>
> renaming it to config_endpoint.c.  A pjsip_ami.c might be in order as<br>
> well for common pjsip cli stuff.<br>
><br>
When it comes to file layout I am more of a fan of grouping<br>
functionality along with the object type.  Personally I would rather see<br>
the ami commands for endpoints in with the endpoints and not group with<br>
ami commands for other types.<br>
<br>
That being said I'd be fine with for instance config_auth.c,<br>
config_auth_ami.c, config_auth_cli.c if one was so inclined.<br>
<br>
I'd also be fine with renaming pjsip_configuration to config_endpoint.<br>
<br></blockquote><div>I wouldn't go down to config_auth_cli level.  config_auth should have all auth related code whether CLI or AMI but there's CLI code at the pjsip level that's not object specific that should probably come out of pjsip_configuration and go in a pjsip_cli.c file.  </div>
<div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
><br>
> Am I overthinking all of this? It's all perfectly clear in MY mind. :)<br>
><br>
I am quite sure I am :-)<br>
<span><font color="#888888"><br>
<br></font></span></blockquote></div></div></div>