diff options
Diffstat (limited to 'lib/chef_zero/endpoints/rest_object_endpoint.rb')
-rw-r--r-- | lib/chef_zero/endpoints/rest_object_endpoint.rb | 42 |
1 files changed, 36 insertions, 6 deletions
diff --git a/lib/chef_zero/endpoints/rest_object_endpoint.rb b/lib/chef_zero/endpoints/rest_object_endpoint.rb index 9e978b4..efadf82 100644 --- a/lib/chef_zero/endpoints/rest_object_endpoint.rb +++ b/lib/chef_zero/endpoints/rest_object_endpoint.rb @@ -21,12 +21,11 @@ module ChefZero def put(request) # We grab the old body to trigger a 404 if it doesn't exist old_body = get_data(request) - request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false) - key = identity_keys.map { |k| request_json[k] }.select { |v| v }.first - key ||= request.rest_path[-1] + # If it's a rename, check for conflict and delete the old value - rename = key != request.rest_path[-1] - if rename + if is_rename?(request) + key = identity_key_value(request) + begin create_data(request, request.rest_path[0..-2], key, request.body, :data_store_exceptions) rescue DataStore::DataAlreadyExistsError @@ -46,18 +45,49 @@ module ChefZero already_json_response(200, populate_defaults(request, result)) end - def patch_request_body(request) + # Merge the request body with the existing data, if one exists in + # the data store + # + # @param [ChefZero::RestRequest] request + # @param [Hash] options + # @option options [Symbol, Array<Symbol>] :except (nil) Key(s) from + # the existing data to discard + def patch_request_body(request, options={}) existing_value = get_data(request, nil, :nil) + if existing_value request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false) existing_json = FFI_Yajl::Parser.parse(existing_value, :create_additions => false) + + if options[:except] + Array(options[:except]).each do |except_key| + existing_json.delete(except_key) + end + end + merged_json = existing_json.merge(request_json) + if merged_json.size > request_json.size return FFI_Yajl::Encoder.encode(merged_json, :pretty => true) end end + request.body end + + private + + # Get the value of the (first existing) identity key from the request body or nil + def identity_key_value(request) + request_json = FFI_Yajl::Parser.parse(request.body, :create_additions => false) + identity_keys.map { |k| request_json[k] }.compact.first + end + + # Does this request change the value of the identity key? + def is_rename?(request) + return false unless key = identity_key_value(request) + key != request.rest_path[-1] + end end end end |