Kaynağa Gözat

HUE-8155 [metadata] Only send modified custom Navigator metadata to prevent setting stale data

Johan Ahlen 7 yıl önce
ebeveyn
işleme
9edcdf0b4f

+ 16 - 2
desktop/core/src/desktop/static/desktop/js/apiHelper.js

@@ -400,6 +400,8 @@ var ApiHelper = (function () {
    * @param {function} [options.successCallback]
    * @param {function} [options.errorCallback]
    * @param {boolean} [options.silenceErrors]
+   *
+   * @return {Promise}
    */
   ApiHelper.prototype.simplePost = function (url, data, options) {
     var self = this;
@@ -1667,6 +1669,18 @@ var ApiHelper = (function () {
     return new CancellablePromise(deferred, request);
   };
 
+  /**
+   * Updates Navigator properties and custom metadata for the given entity
+   *
+   * @param {Object} options
+   * @param {string} options.identity - The identifier for the Navigator entity to update
+   * @param {Object} [options.properties]
+   * @param {Object} [options.modifiedCustomMetadata]
+   * @param {string[]} [options.deletedCustomMetadataKeys]
+   * @param {boolean} [options.silenceErrors]
+   *
+   * @return {Promise}
+   */
   ApiHelper.prototype.updateNavigatorProperties = function (options) {
     var self = this;
     var data = { id: ko.mapping.toJSON(options.identity) };
@@ -1674,8 +1688,8 @@ var ApiHelper = (function () {
     if (options.properties) {
       data.properties = ko.mapping.toJSON(options.properties);
     }
-    if (options.customMetadata) {
-      data.customMetadata = ko.mapping.toJSON(options.customMetadata);
+    if (options.modifiedCustomMetadata) {
+      data.modifiedCustomMetadata = ko.mapping.toJSON(options.modifiedCustomMetadata);
     }
     if (options.deletedCustomMetadataKeys) {
       data.deletedCustomMetadataKeys = ko.mapping.toJSON(options.deletedCustomMetadataKeys);

+ 12 - 2
desktop/core/src/desktop/static/desktop/js/dataCatalog.js

@@ -1115,7 +1115,17 @@ var DataCatalog = (function () {
       return applyCancellable(new CancellablePromise(deferred, undefined, cancellablePromises), options);
     };
 
-    DataCatalogEntry.prototype.updateNavigatorCustomMetadata = function (customMetadata, deletedCustomMetadataKeys, apiOptions) {
+    /**
+     * Updates custom navigator metadata for the catalog entry
+     *
+     * @param {Object} [modifiedCustomMetadata] - The custom metadata to update, only supply what has been changed
+     * @param {string[]} [deletedCustomMetadataKeys] - The custom metadata to delete identifier by the keys
+     * @param {Object} [apiOptions]
+     * @param {boolean} [apiOptions.silenceErrors]
+     *
+     * @return {Promise}
+     */
+    DataCatalogEntry.prototype.updateNavigatorCustomMetadata = function (modifiedCustomMetadata, deletedCustomMetadataKeys, apiOptions) {
       var self = this;
       var deferred = $.Deferred();
 
@@ -1130,7 +1140,7 @@ var DataCatalog = (function () {
           if (navigatorMeta) {
             ApiHelper.getInstance().updateNavigatorProperties({
               identity: navigatorMeta.identity,
-              customMetadata: customMetadata,
+              modifiedCustomMetadata: modifiedCustomMetadata,
               deletedCustomMetadataKeys: deletedCustomMetadataKeys
             }).done(function (entity) {
               if (entity) {

+ 22 - 12
desktop/core/src/desktop/templates/ko_components/ko_nav_properties.mako

@@ -182,19 +182,29 @@ from django.utils.translation import ugettext as _
         $(document).off('click.navProperties');
         self.editMode(false);
         if (ko.mapping.toJSON(self.editProperties()) !== ko.mapping.toJSON(self.properties())) {
-          var customMetadata = {};
-          self.editProperties().forEach(function (property) {
-            customMetadata[property.key()] = property.value();
-          });
-          var deletedCustomMetadataKeys = [];
-          self.properties().forEach(function (property) {
-            if (!customMetadata[property.key()]) {
-              deletedCustomMetadataKeys.push(property.key());
-            }
-          });
-
           self.loading(true);
-          self.catalogEntry.updateNavigatorCustomMetadata(customMetadata, deletedCustomMetadataKeys).always(function () {
+          self.catalogEntry.getNavigatorMeta().done(function (navigatorMeta) {
+            var keysAfterEdit = {};
+            var modifiedCustomMetadata = {};
+
+            self.editProperties().forEach(function (property) {
+              if (navigatorMeta.properties[property.key()] !== property.value()) {
+                modifiedCustomMetadata[property.key()] = property.value();
+              }
+              keysAfterEdit[property.key()] = true;
+            });
+
+            var deletedCustomMetadataKeys = [];
+            self.properties().forEach(function (property) {
+              if (!keysAfterEdit[property.key()]) {
+                deletedCustomMetadataKeys.push(property.key());
+              }
+            });
+
+            self.catalogEntry.updateNavigatorCustomMetadata(modifiedCustomMetadata, deletedCustomMetadataKeys).always(function () {
+              self.loadProperties();
+            });
+          }).fail(function () {
             self.loadProperties();
           });
         }

+ 3 - 3
desktop/libs/metadata/src/metadata/navigator_api.py

@@ -455,7 +455,7 @@ def update_properties(request):
   api = NavigatorApi(request.user)
   entity_id = json.loads(request.POST.get('id', '""'))
   properties = json.loads(request.POST.get('properties', '{}')) # Entity properties
-  custom_metadata = json.loads(request.POST.get('customMetadata', '{}')) # Aka "Custom Metadata"
+  modified_custom_metadata = json.loads(request.POST.get('modifiedCustomMetadata', '{}')) # Aka "Custom Metadata"
   deleted_custom_metadata_keys = json.loads(request.POST.get('deletedCustomMetadataKeys', '[]'))
 
   is_allowed = request.user.has_hue_permission(action='write', app='metadata')
@@ -463,7 +463,7 @@ def update_properties(request):
   request.audit = {
     'allowed': is_allowed,
     'operation': 'NAVIGATOR_UPDATE_PROPERTIES',
-    'operationText': 'Updating custom metadata %s, deleted custom metadata keys %s and properties %s of entity %s' % (custom_metadata, deleted_custom_metadata_keys, properties, entity_id)
+    'operationText': 'Updating custom metadata %s, deleted custom metadata keys %s and properties %s of entity %s' % (modified_custom_metadata, deleted_custom_metadata_keys, properties, entity_id)
   }
 
   if not entity_id:
@@ -475,7 +475,7 @@ def update_properties(request):
     # TODO: HueAuthException?
     raise Exception("The user does not have proper Hue permissions to update Navigator properties.")
 
-  return JsonResponse(api.update_properties(entity_id, properties, custom_metadata, deleted_custom_metadata_keys))
+  return JsonResponse(api.update_properties(entity_id, properties, modified_custom_metadata, deleted_custom_metadata_keys))
 
 
 @require_POST

+ 5 - 5
desktop/libs/metadata/src/metadata/navigator_client.py

@@ -473,14 +473,14 @@ class NavigatorApi(object):
     return self.update_entity(entity, tags=new_tags)
 
 
-  def update_properties(self, entity_id, properties, custom_properties=None, deleted_custom_properties=None):
+  def update_properties(self, entity_id, properties, modified_custom_metadata=None, deleted_custom_metadata_keys=None):
     entity = self.get_entity(entity_id)
-    if custom_properties:
+    if modified_custom_metadata:
       properties['properties'] = entity['properties'] or {}
-      properties['properties'].update(custom_properties)
-    if deleted_custom_properties:
+      properties['properties'].update(modified_custom_metadata)
+    if deleted_custom_metadata_keys:
       properties['properties'] = entity['properties'] or {}
-      for key in deleted_custom_properties:
+      for key in deleted_custom_metadata_keys:
         if key in properties['properties']:
           del properties['properties'][key]
     return self.update_entity(entity, **properties)