Эх сурвалжийг харах

HUE-7820 [metadata] Properly update entities properties or custom metadata

There was a mix between entity properties (e.g. name, description...) and its custom metadata (properties dict).
Add bunch of protection to not fail on json parse in API.
Delete custom metadata API not used anywhere.
Romain Rigaux 7 жил өмнө
parent
commit
3110e9ea30

+ 17 - 16
desktop/libs/metadata/src/metadata/navigator_api.py

@@ -407,8 +407,8 @@ def add_tags(request):
   response = {'status': -1}
   response = {'status': -1}
 
 
   api = NavigatorApi(request.user)
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  tags = json.loads(request.POST.get('tags', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  tags = json.loads(request.POST.get('tags', "[]"))
 
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
 
@@ -433,8 +433,8 @@ def delete_tags(request):
   response = {'status': -1}
   response = {'status': -1}
 
 
   api = NavigatorApi(request.user)
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  tags = json.loads(request.POST.get('tags', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  tags = json.loads(request.POST.get('tags', '[]'))
 
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
 
@@ -459,21 +459,22 @@ def update_properties(request):
   response = {'status': -1}
   response = {'status': -1}
 
 
   api = NavigatorApi(request.user)
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  properties = json.loads(request.POST.get('properties', {}))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  properties = json.loads(request.POST.get('properties', '{}')) # Entity properties
+  metadata = json.loads(request.POST.get('metadata', '{}')) # Aka "Custom Metadata"
 
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
 
   request.audit = {
   request.audit = {
     'allowed': is_allowed,
     'allowed': is_allowed,
     'operation': 'NAVIGATOR_UPDATE_PROPERTIES',
     'operation': 'NAVIGATOR_UPDATE_PROPERTIES',
-    'operationText': 'Updating property %s of entity %s' % (properties, entity_id)
+    'operationText': 'Updating metadata %s properties %s of entity %s' % (metadata, properties, entity_id)
   }
   }
 
 
-  if not entity_id or not properties or not isinstance(properties, dict) or not is_allowed:
-    response['error'] = _("update_properties requires an 'id' parameter and 'properties' parameter that is a non-empty dict")
+  if not entity_id or (not properties and not metadata) or not is_allowed:
+    response['error'] = _("update_properties requires an 'id' parameter and 'properties' or 'metadata' parameters that are non-empty dicts")
   else:
   else:
-    response['entity'] = api.update_properties(entity_id, properties)
+    response['entity'] = api.update_properties(entity_id, properties, metadata)
     response['status'] = 0
     response['status'] = 0
 
 
   return JsonResponse(response)
   return JsonResponse(response)
@@ -481,25 +482,25 @@ def update_properties(request):
 
 
 @require_POST
 @require_POST
 @error_handler
 @error_handler
-def delete_properties(request):
+def delete_metadata_properties(request):
   response = {'status': -1}
   response = {'status': -1}
 
 
   api = NavigatorApi(request.user)
   api = NavigatorApi(request.user)
-  entity_id = json.loads(request.POST.get('id', ''))
-  keys = json.loads(request.POST.get('keys', []))
+  entity_id = json.loads(request.POST.get('id', '""'))
+  keys = json.loads(request.POST.get('keys', '[]'))
 
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
 
 
   request.audit = {
   request.audit = {
     'allowed': is_allowed,
     'allowed': is_allowed,
-    'operation': 'NAVIGATOR_DELETE_PROPERTIES',
-    'operationText': 'Deleting property %s of entity %s' % (keys, entity_id)
+    'operation': 'NAVIGATOR_DELETE_METADATA_PROPERTIES',
+    'operationText': 'Deleting metadata %s of entity %s' % (keys, entity_id)
   }
   }
 
 
   if not entity_id or not keys or not isinstance(keys, list):
   if not entity_id or not keys or not isinstance(keys, list):
     response['error'] = _("update_properties requires an 'id' parameter and 'keys' parameter that is a non-empty list")
     response['error'] = _("update_properties requires an 'id' parameter and 'keys' parameter that is a non-empty list")
   else:
   else:
-    response['entity'] = api.delete_properties(entity_id, keys)
+    response['entity'] = api.delete_metadata_properties(entity_id, keys)
     response['status'] = 0
     response['status'] = 0
 
 
   return JsonResponse(response)
   return JsonResponse(response)

+ 7 - 6
desktop/libs/metadata/src/metadata/navigator_client.py

@@ -460,14 +460,15 @@ class NavigatorApi(object):
     return self.update_entity(entity_id, tags=new_tags)
     return self.update_entity(entity_id, tags=new_tags)
 
 
 
 
-  def update_properties(self, entity_id, properties):
-    entity = self.get_entity(entity_id)
-    new_props = entity['properties'] or {}
-    new_props.update(properties)
-    return self.update_entity(entity_id, properties=new_props)
+  def update_properties(self, entity_id, properties, metadata=None):
+    if metadata:
+      entity = self.get_entity(entity_id)
+      properties['properties'] = entity['properties'] or {}
+      properties['properties'].update(metadata)
+    return self.update_entity(entity_id, **properties)
 
 
 
 
-  def delete_properties(self, entity_id, property_keys):
+  def delete_metadata_properties(self, entity_id, property_keys):
     entity = self.get_entity(entity_id)
     entity = self.get_entity(entity_id)
     new_props = entity['properties'] or {}
     new_props = entity['properties'] or {}
     for key in property_keys:
     for key in property_keys:

+ 1 - 1
desktop/libs/metadata/src/metadata/navigator_tests.py

@@ -118,7 +118,7 @@ class TestNavigator(object):
     props.update({'hue': 'test'})
     props.update({'hue': 'test'})
     assert_equal(props, json_resp['entity']['properties'])
     assert_equal(props, json_resp['entity']['properties'])
 
 
-    resp = self.client.post(reverse('metadata:delete_properties'), self._format_json_body({'id': entity_id, 'keys': ['hue']}))
+    resp = self.client.post(reverse('metadata:delete_metadata_properties'), self._format_json_body({'id': entity_id, 'keys': ['hue']}))
     json_resp = json.loads(resp.content)
     json_resp = json.loads(resp.content)
     assert_equal(0, json_resp['status'], json_resp)
     assert_equal(0, json_resp['status'], json_resp)
     del props['hue']
     del props['hue']

+ 1 - 1
desktop/libs/metadata/src/metadata/urls.py

@@ -29,7 +29,7 @@ urlpatterns = patterns('metadata.navigator_api',
   url(r'^api/navigator/list_tags/?$', 'list_tags', name='list_tags'),
   url(r'^api/navigator/list_tags/?$', 'list_tags', name='list_tags'),
   url(r'^api/navigator/suggest/?$', 'suggest', name='suggest'),
   url(r'^api/navigator/suggest/?$', 'suggest', name='suggest'),
   url(r'^api/navigator/update_properties/?$', 'update_properties', name='update_properties'),
   url(r'^api/navigator/update_properties/?$', 'update_properties', name='update_properties'),
-  url(r'^api/navigator/delete_properties/?$', 'delete_properties', name='delete_properties'),
+  url(r'^api/navigator/delete_metadata_properties/?$', 'delete_metadata_properties', name='delete_metadata_properties'),
   url(r'^api/navigator/lineage/?$', 'get_lineage', name='get_lineage'),
   url(r'^api/navigator/lineage/?$', 'get_lineage', name='get_lineage'),
 )
 )