Re: [Engine-devel] Logical network Usages collection problematic approach

The new design of logical network 'usages' collection came out a bit problematic or shall i say annoying. The idea is to send the entire collection elements every time a user wants to update a single usage otherwise the missing elements will be automatically removed from the collection.
Example: having <usages><usage>VM</usage><usages> 1. in order to add 'display' usage to the collection i must send 'vm' as well. 2. to remove an element from the collection, i must send the entire collection without the desired element (note: in this case it is only one extra element for every update but in other cases it could be much more)
Yep, this seems to conflict with the general idiom around the interpretation of missing properties in a PUT representation - i.e. any properties omitted from the representation are ignored and not changed.
The solution should be: <usages><vm>true</vm><display>false</display></usages> That way we can send a single usage having different boolean text without including the entire collection elements.
I wonder would a POST/DELETE idiom be more natural, if the individual usages would be pressed into service as a psuedo-OID, e.g: POST .../networks/network_id/usages HTTP/1.1 <usage id="VM"/> 201 Created Location: .../networks/network_id/usages/VM <usage id="VM" href=".../networks/network_id/usages/VM"/> -- GET .../networks/network_id/usages HTTP/1.1 200 OK Location: .../networks/network_id/usages/VM <usages> <usage id="VM" href=".../networks/network_id/usages/VM"/> </usages> -- POST .../networks/network_id/usages HTTP/1.1 <usage id="display"/> 201 Created Location: .../networks/network_id/usages/display <usage id="display" href=".../networks/network_id/usages/display"/> -- GET .../networks/network_id/usages HTTP/1.1 200 OK <usages> <usage id="VM" href=".../networks/network_id/usages/VM"/> <usage id="display" href=".../networks/network_id/usages/display"/> <usages> -- DELETE .../networks/network_id/usages/VM 204 No Content -- GET .../networks/network_id/usages HTTP/1.1 200 OK <usages> <usage id="display" href=".../networks/network_id/usages/display"/> <usages> So from each usage would appear like a first class resource from the perspective of the creation/deletion idiom. If the client providing the ID is considered inconsistent, this could be a "name" child element instead, e.g.: POST .../networks/network_id/usages HTTP/1.1 <usage> <name>display</name> </usage> 201 Created Location: .../networks/network_id/usages/display <usage id="display" href=".../networks/network_id/usages/display"> <name>display</name> </usage> Cheers, Eoghan

The new design of logical network 'usages' collection came out a bit problematic or shall i say annoying. The idea is to send the entire collection elements every time a user wants to update a single usage otherwise the missing elements will be automatically removed from the collection.
Example: having <usages><usage>VM</usage><usages> 1. in order to add 'display' usage to the collection i must send 'vm' as well. 2. to remove an element from the collection, i must send the entire collection without the desired element (note: in this case it is only one extra element for every update but in other cases it could be much more)
Yep, this seems to conflict with the general idiom around the interpretation of missing properties in a PUT representation - i.e. any properties omitted from the representation are ignored and not changed.
**I'm going to explain the current modelling; this does not mean I object to other modellings** In the current modelling, usages are a non-trivial collection within a Network, but they are not business entities, and thus do not have their own 'context' (i.e, there's no: .../networks/{network:id}/usages). This is not new to our API; VM Custom Properties behave in the same way. If user doesn't pass custom-properties when updating a VM, they are unchanged. But if he passes <custom_properties> element, then its contents *replace* the previous context. This means effectively that if an existing custom property isn't there - it will be deleted. I understood from Avi (although I don't think you mentioned it in this mail), that there's a bug, that if the user doesn't pass <usages> at all - they will all be deleted. This is off course a bug, and it will be fixed. But if user passes empty <usages> then yes, they all will be deleted.
The solution should be: <usages><vm>true</vm><display>false</display></usages> That way we can send a single usage having different boolean text without including the entire collection elements.
I wonder would a POST/DELETE idiom be more natural, if the individual usages would be pressed into service as a psuedo-OID, e.g:
POST .../networks/network_id/usages HTTP/1.1 <usage id="VM"/>
201 Created Location: .../networks/network_id/usages/VM <usage id="VM" href=".../networks/network_id/usages/VM"/>
--
GET .../networks/network_id/usages HTTP/1.1
200 OK Location: .../networks/network_id/usages/VM <usages> <usage id="VM" href=".../networks/network_id/usages/VM"/> </usages>
--
POST .../networks/network_id/usages HTTP/1.1 <usage id="display"/>
201 Created Location: .../networks/network_id/usages/display <usage id="display" href=".../networks/network_id/usages/display"/>
--
GET .../networks/network_id/usages HTTP/1.1
200 OK <usages> <usage id="VM" href=".../networks/network_id/usages/VM"/> <usage id="display" href=".../networks/network_id/usages/display"/> <usages>
--
DELETE .../networks/network_id/usages/VM
204 No Content
--
GET .../networks/network_id/usages HTTP/1.1
200 OK <usages> <usage id="display" href=".../networks/network_id/usages/display"/> <usages>
So from each usage would appear like a first class resource from the perspective of the creation/deletion idiom. If the client providing the ID is considered inconsistent, this could be a "name" child element instead, e.g.:
POST .../networks/network_id/usages HTTP/1.1 <usage> <name>display</name> </usage>
201 Created Location: .../networks/network_id/usages/display <usage id="display" href=".../networks/network_id/usages/display"> <name>display</name> </usage>
We'd need to develop an infrastructure for generating on-the-fly IDs for internal, non-entity, collections (based on a specified field) - and then correctly following links that contain these IDs. I like it, but it won't be trivial, so the question is - is now the time to do it? Ori.
Cheers, Eoghan

The new design of logical network 'usages' collection came out a bit problematic or shall i say annoying. The idea is to send the entire collection elements every time a user wants to update a single usage otherwise the missing elements will be automatically removed from the collection.
Example: having <usages><usage>VM</usage><usages> 1. in order to add 'display' usage to the collection i must send 'vm' as well. 2. to remove an element from the collection, i must send the entire collection without the desired element (note: in this case it is only one extra element for every update but in other cases it could be much more)
Yep, this seems to conflict with the general idiom around the interpretation of missing properties in a PUT representation - i.e. any properties omitted from the representation are ignored and not changed.
**I'm going to explain the current modelling; this does not mean I object to other modellings**
In the current modelling, usages are a non-trivial collection within a Network, but they are not business entities, and thus do not have their own 'context' (i.e, there's no: .../networks/{network:id}/usages).
A-ha, I see. I was thrown by the overloading on the term "collection", which I would have understood as a set of resources that may be addressed as a group. Whereas in fact we're more talking about an aspect of the Network representation that happens to include boolean sub-elements, right? In which case, making this explicit via your suggestion: <usages><vm>true</vm><display>false</display></usages> would seem reasonable on the face of it. However there's an implementation wrinkle in the type-mapper framework ... I'd understand the PUT below as meaning: "set the VM usage to true, and leave other usages as they are". GET .../networks/{network:id} HTTP/1.1 200 OK <network id="{network:id}"> ... <usages><display>true</display></usages> </network> -- PUT .../networks/{network:id} HTTP/1.1 <network id="{network:id}"> <usages><vm>true</vm></usages> </network> 200 OK <network id="{network:id}"> ... <usages> <vm>true</vm> <display>true</display> </usages> </network> as things currently stand, the type mapper called prior to the UpdateNetwork action being initiated doesn't have access to the *existing* network entity, so it has no way of setting the is_display flag on the mapped entity to match the pre-existing setting. I guess you could work around this by forcing a network lookup *prior* to the update, so that the pre-existing display setting is available, and then pass this entity as a template into the type mapping.
I wonder would a POST/DELETE idiom be more natural, if the individual usages would be pressed into service as a psuedo-OID, e.g: [snip]
We'd need to develop an infrastructure for generating on-the-fly IDs for internal, non-entity, collections (based on a specified field)
Well, the idea was to avoid the need for generating on-the-fly OIDs, by reusing the display "name" as the OID. But yes, it would still involve some deviation from the established collection/sub-resource implementation patterns. Cheers, Eoghan
participants (2)
-
Eoghan Glynn
-
Ori Liel