lib/elasticsearch-serverless/api/utils.rb (59 lines of code) (raw):

# Licensed to Elasticsearch B.V. under one or more contributor # license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright # ownership. Elasticsearch B.V. licenses this file to you under # the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. require 'json' require 'erb' module ElasticsearchServerless module API module Utils def self.process_params(arguments) arguments = Hash[arguments] unless arguments.is_a?(Hash) Hash[arguments.map { |k, v| v.is_a?(Array) ? [k, listify(v, { escape: false })] : [k, v] }] # Listify Arrays end # Convert an array of payloads into Elasticsearch `header\ndata` format # # Supports various different formats of the payload: Array of Strings, Header/Data pairs, # or the conveniency "combined" format where data is passed along with the header # in a single item. # # Elasticsearch::API::Utils.bulkify [ # { :index => { :_index => 'myindexA', :_type => 'mytype', :_id => '1', :data => { :title => 'Test' } } }, # { :update => { :_index => 'myindexB', :_type => 'mytype', :_id => '2', :data => { :doc => { :title => 'Update' } } } } # ] # # # => {"index":{"_index":"myindexA","_type":"mytype","_id":"1"}} # # => {"title":"Test"} # # => {"update":{"_index":"myindexB","_type":"mytype","_id":"2"}} # # => {"doc":{"title":"Update"}} # def self.bulkify(payload) operations = %w[index create delete update] case # Hashes with `:data` when payload.any? { |d| d.is_a?(Hash) && d.values.first.is_a?(Hash) && operations.include?(d.keys.first.to_s) && (d.values.first[:data] || d.values.first['data']) } payload = payload .inject([]) do |sum, item| operation, meta = item.to_a.first meta = meta.clone data = meta.delete(:data) || meta.delete('data') sum << { operation => meta } sum << data if data sum end.map { |item| JSON.dump(item) } payload << '' unless payload.empty? # Array of strings when payload.all? { |d| d.is_a? String } payload << '' # Header/Data pairs else payload = payload.map { |item| JSON.dump(item) } payload << '' end payload = payload.join("\n") end # Create a "list" of values from arguments, ignoring nil values and encoding special characters. # # @example Create a list from array # listify(['A','B']) # => 'A,B' # # @example Create a list from arguments # listify('A','B') # => 'A,B' # # @example Escape values # listify('foo','bar^bam') # => 'foo,bar%5Ebam' # # @example Do not escape the values # listify('foo','bar^bam', escape: false) # => 'foo,bar^bam' # # @api private def self.listify(*list) options = list.last.is_a?(Hash) ? list.pop : {} escape = options[:escape] Array(list) .flat_map { |e| e.respond_to?(:split) ? e.split(',') : e } .flatten .compact .map { |e| escape == false ? e : escape(e) } .join(',') end # URL-escape a string # # @example # __escape('foo/bar') # => 'foo%2Fbar' # __escape('bar^bam') # => 'bar%5Ebam' # # @api private def self.escape(string) return string if string == '*' ERB::Util.url_encode(string.to_s) end # Calls the given block, rescuing from `StandardError`. # # Primary use case is the `:ignore` parameter for API calls. # # Returns `false` if exception contains NotFound in its class name or message, # else re-raises the exception. # # @yield [block] A block of code to be executed with exception handling. # # @api private # def self.rescue_from_not_found(&block) yield rescue StandardError => e if e.class.to_s =~ /NotFound/ || e.message =~ /Not\s*Found/i false else raise e end end end end end