I just re-read and I apologize for the hastily written email I previously sent. I’ll try to salvage it with a bit of a revision below (please ignore the previous email).
On 12/11/14, 7:02 PM, "Tripp, Travis S" <travis.tr...@hp.com> wrote (REVISED): >Tihomir, > >Your comments in the patch were very helpful for me to understand your >concerns about the ease of customizing without requiring upstream >changes. It also reminded me that I’ve also previously questioned the >python middleman. > >However, here are a couple of bullet points for Devil’s Advocate >consideration. > > > * Will we take on auto-discovery of API extensions in two spots >(python for legacy and JS for new)? > * The Horizon team will have to keep an even closer eye on every >single project and be ready to react if there are changes to the API that >break things. Right now in Glance, for example, they are working on some >fixes to the v2 API (soon to become v2.3) that will allow them to >deprecate v1 somewhat transparently to users of the client library. > * The service API documentation almost always lags (although, helped >by specs now) and the service team takes on the burden of exposing a >programmatic way to access the API. This is tested and easily consumable >via the python clients, which removes some guesswork from using the >service. > * This is going to be an incremental approach with legacy support >requirements anyway. So, incorporating python side changes won’t just go >away. > * Which approach would be better if we introduce a server side >caching mechanism or a new source of data such as elastic search to >improve performance? Would the client side code have to be changed >dramatically to take advantage of those improvements or could it be done >transparently on the server side if we own the exposed API? > >I’m not sure I fully understood your example about Cinder. Was it the >cinder client that held up delivery of horizon support, the cinder API or >both? If the API isn’t in, then it would hold up delivery of the feature >in any case. There still would be timing pressures to react and build a >new view that supports it. For customization, with Richard’s approach new >views could be supported by just dropping in a new REST API decorated >module with the APIs you want, including direct pass through support if >desired to new APIs. Downstream customizations / Upstream changes to >views seem a bit like a bit of a related, but different issue to me as >long as their is an easy way to drop in new API support. > >Finally, regarding the client making two calls to do an update: > >>>Do we really need the lines: > >>> project = api.keystone.tenant_get(request, id) >>> kwargs = _tenant_kwargs_from_DATA(request.DATA, enabled=None) > >I agree that if you already have all the data it may be bad to have to do >another call. I do think there is room for discussing the reasoning, >though. >As far as I can tell, they do this so that if you are updating an entity, >you have to be very specific about the fields you are changing. I >actually see this as potentially a protectionary measure against data >loss and sometimes a very nice to have feature. It perhaps was intended >to *help* guard against race conditions (no locking and no transactions >with many users simultaneously accessing the data). > >Here's an example: Admin user Joe has a Domain open and stares at it for >15 minutes while he updates just the description. Admin user Bob is asked >to go ahead and enable it. He opens the record, edits it, and then saves >it. Joe finished perfecting the description and saves it. They could in >effect both edit the same domain independently. Last man in still wins if >he updates the same fields, but if they update different fields then both >of their changes will take affect without them stomping on each other. Or >maybe it is intended to encourage client users to compare their current >and previous to see if they should issue a warning if the data changed >between getting and updating the data. Or maybe like you said, it is just >overhead API calls. > >From: Tihomir Trifonov <t.trifo...@gmail.com<mailto:t.trifo...@gmail.com>> >Reply-To: OpenStack List ><openstack-dev@lists.openstack.org<mailto:openstack-...@lists.openstack.or >g>> >Date: Thursday, December 11, 2014 at 7:53 AM >To: OpenStack List ><openstack-dev@lists.openstack.org<mailto:openstack-...@lists.openstack.or >g>> >Subject: Re: [openstack-dev] [horizon] REST and Django > > >Client just needs to know which URL to hit in order to invoke a certain >API, and does not need to know the procedure name or parameters ordering. > > >That's where the difference is. I think the client has to know the >procedure name and parameters. Otherwise we have a translation factory >pattern, that converts one naming convention to another. And you won't be >able to call any service API if there is no code in the middleware to >translate it to the service API procedure name and parameters. To avoid >this - we can use a transparent proxy model - direct mapping of a client >call to service API naming, which can be done if the client invokes the >methods with the names in the service API, so that the middleware will >just pass parameters, and will not translate. Instead of: > > >updating user data: > > <client: POST /user/ > => <middleware: convert to >/keystone/update/ > => <keystone: update> > >we may use: > > <client: POST /keystone/{ver:=x.0}/{method:=update} > => ><middleware: just forward to clients[ver].getattr("method")(**kwargs) > >=> <keystone: update> > > >The idea here is that if we have keystone 4.0 client, we will have to >just add it to the clients [] list and nothing more is required at the >middleware level. Just create the frontend code to use the new Keystone >4.0 methods. Otherwise we will have to add all new/different signatures >of 4.0 against 2.0/3.0 in the middleware in order to use Keystone 4.0. > >There is also a great example of using a pluggable/new feature in >Horizon. Do you remember the volume types support patch? The patch was >pending in Gerrit for few months - first waiting the cinder support for >volume types to go upstream, then waiting few more weeks for review. I am >not sure, but as far as I remember, the Horizon patch even missed a >release milestone and was introduced in the next release. > >If we have a transparent middleware - this will be no more an issue. As >long as someone has written the frontend modules(which should be easy to >add and customize), and they install the required version of the service >API - they will not need updated Horizon to start using the feature. >Maybe I am not the right person to give examples here, but how many of >you had some kind of Horizon customization being locally merged/patched >in your local distros/setups, until the patch is being pushed upstream? > >I will say it again. Nova, Keystone, Cinder, Glance etc. already have >stable public APIs. Why do we want to add the translation middleware and >to introduce another level of REST API? This layer will often hide new >features, added to the service APIs and will delay their appearance in >Horizon. That's simply not needed. I believe it is possible to just wrap >the authentication in the middleware REST, but not to translate anything >as RPC methods/parameters. > > >And one more example: > >@rest_utils.ajax() >def put(self, request, id): > """Update a single project. > > The POST data should be an application/json object containing the > parameters to update: "name" (string), "description" (string), > "domain_id" (string) and "enabled" (boolean, defaults to true). > Additional, undefined parameters may also be provided, but you'll >have > to look deep into keystone to figure out what they might be. > > This method returns HTTP 204 (no content) on success. > """ > project = api.keystone.tenant_get(request, id) > kwargs = _tenant_kwargs_from_DATA(request.DATA, enabled=None) > api.keystone.tenant_update(request, project, **kwargs) > >Do we really need the lines: > >project = api.keystone.tenant_get(request, id) >kwargs = _tenant_kwargs_from_DATA(request.DATA, enabled=None) > >? Since we update the project on the client, it is obvious that we >already fetched the project data. So we can simply send: > > >POST /keystone/3.0/tenant_update > >Content-Type: application/json > >{"id": cached.id<http://cached.id>, "domain_id": cached.domain_id, >"name": "new name", "description": "new description", "enabled": >cached.enabled} > >Fewer requests, faster application. > > _______________________________________________ OpenStack-dev mailing list OpenStack-dev@lists.openstack.org http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev