Unsolved
This post is more than 5 years old
3 Posts
1
1240
March 13th, 2014 08:00
ViPR REST API issue
I am using the REST API to get a catalog service descriptor as shown below. To retrieve options for each field, we are supposed to query the /api/options/*** URL. There are some fields whose options have dependencies on previously selected values, what the ViPR docs refer to as Upstream Values. To properly handle upstream values, we are supposed to query the field list in the order it was returned in the descriptor.
I have run into an issue where the first field returned in the descriptor has upstream dependencies on a later field. This is for the standard catalog item to Create Volume and Datastore under VMware Block Services as shown in the descriptor below. The first field - datacenter - has a dependency on the vcenter field, further on down the descriptor. While I can work around this for my current purposes, if my goal were to be fully automated, there would be no way for my application to figure out the proper dependency order.
JSON Descriptor |
---|
DEBUG:requests.packages.urllib3.connectionpool:"GET /api/services/urn:storageos:CatalogService:de5cee60-8abd-4ac0-becf-daca94ddd9ed:/descriptor HTTP/1.1" 200 4166 { "category": "VMware Block Services", "description": "Create block volume and VMware Datastore.", "roles": [], "title": "Create Volume and Datastore", "fields": { "datacenter": { "name": "datacenter", "required": true, "label": "Datacenter", "lockable": false, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.datacenter", "options": {}, "select": "one" }, "name": { "description": "User assigned description of the volume", "required": true, "label": "Name", "lockable": false, "validation": { "regEx": "", "max": 128, "failureMessage": "", "min": 2 }, "type": "text", "options": {}, "select": "one", "name": "name" }, "virtualPool": { "name": "virtualPool", "required": true, "label": "Virtual Pool", "lockable": true, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.blockVirtualPool", "options": {}, "select": "one" }, "datastoreName": { "name": "datastoreName", "required": true, "label": "Datastore Name", "lockable": false, "validation": { "regEx": "[a-zA-Z0-9 \\-\\_]+", "max": 128, "failureMessage": "", "min": 2 }, "type": "text", "options": {}, "select": "one" }, "virtualArray": { "name": "virtualArray", "required": true, "label": "Virtual Array", "lockable": true, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.virtualArray", "options": {}, "select": "one" }, "project": { "name": "project", "required": true, "label": "Project", "lockable": true, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.project", "options": {}, "select": "one" }, "host": { "description": "Host or cluster to allocate storage to", "required": true, "label": "ESX Host/Cluster", "lockable": false, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.esxHost", "options": {}, "select": "one", "name": "host" }, "vcenter": { "name": "vcenter", "required": true, "label": "vCenter", "lockable": false, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.vcenter", "options": {}, "select": "one" }, "consistencyGroup": { "name": "consistencyGroup", "required": false, "label": "Consistency Group", "lockable": false, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.consistencyGroup", "options": {}, "select": "one" }, "blockStorageType": { "initialValue": "shared", "name": "blockStorageType", "required": true, "label": "Storage Type", "lockable": true, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 0 }, "type": "assetType.vipr.blockStorageType", "options": {}, "select": "one" }, "size": { "name": "size", "required": true, "label": "Size (GB)", "lockable": false, "validation": { "regEx": "", "max": 2147483647, "failureMessage": "", "min": 1 }, "type": "storageSize", "options": {}, "select": "one" } }, "serviceId": "VMware-CreateVolumeAndVmfsDatastore", "destructive": false } |
seancummins
2 Intern
•
226 Posts
1
March 26th, 2014 16:00
bkugler,
Perhaps you could try using a Python OrderedDict instead of a standard dictionary?
e.g.
from collections import OrderedDict
myDictionary = OrderedDict()
Then when you populate myDictionary, the order in which you add keys will be preserved.
Thanks,
- Sean
bkugler
3 Posts
1
March 26th, 2014 16:00
Hi, thanks for the reply.
The trouble I'm having is that the JSON data being returned is a dictionary. Specifically the 'fields' key/value pair is a dictionary of items. Dictionaries are by definition unordered so when I read the JSON object into my Python dictionary it does not preserve the order of the key/value pairs in the 'fields' dictionary. In fact, the object shown in my first post is the dictionary as it looks in Python. If I look at the raw JSON data in the packet, the fields are in the 'expected' order.
The standard, for both Python and JSON (RFC 7159) is that dictionaries are unordered, so I would recommend that in future releases, the data structure of the JSON response be altered to follow the RFC specification. In the meantime, I will work around this.
*Note - Python dictionary types are equivalent to JSON object types. I use dictionary interchangeably above.
**Edit -
So the implementation for this was pretty easy. I'm using Python 2.7.6 and the Requests library which has it's own JSON parser. Instead of using Requests' JSON parser, I used the standard Python library JSON parser instead and passed the object_hook_pairs parameter an OrderedDict type. This resolves my issue.
from collections import OrderedDict
...
# resp.content is the unfiltered data that Requests returns
data=json.loads(resp.content,object_pairs_hook=OrderedDict)
# from here data is now an OrderedDict and we can retrieve keys in the order they were received
bkugler
3 Posts
0
March 26th, 2014 16:00
Hi Sean,
Thanks for the reply. I ninja edited my post above with the same thing, pretty much. It was a quick and simple change and didn't effect any of my other logic, so that was great!
I should have caught this sooner, but I was relying on a library to do my parsing for me and didn't look at the underlying data structure closely enough.
seancummins
2 Intern
•
226 Posts
1
March 26th, 2014 16:00
Awesome; glad you got it working.
Thanks,
- Sean