Module: RightScale::CloudApi::Mixin::QueryApiPatterns

Defined in:
lib/base/helpers/query_api_patterns.rb

Overview

Query API namespace

Defined Under Namespace

Modules: ClassMethods

Constant Summary collapse

FIND_KEY_REGEXP =
/\{:([a-zA-Z0-9_]+)\}/
FIND_COLLECTION_1_REGEXP =
/\[\{:([a-zA-Z0-9_]+)\}\]/
FIND_COLLECTION_2_REGEXP =
/^([^\[]+)\[\]/
FIND_REPLACEMENT_REGEXP =
/\{:([a-zA-Z0-9_]+)\}(?!\])/
FIND_BLANK_KEYS_TO_REMOVE =
/\{!remove-if-blank\}/

Class Method Summary collapse

Instance Method Summary collapse

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

Create custom method_missing method

If the called method is not explicitly defined then it tries to find the method definition in the QUERY-like patterns. And if the method is there it builds a request based on the pattern definition.

Examples:

# no example

Returns:



334
335
336
337
338
339
340
# File 'lib/base/helpers/query_api_patterns.rb', line 334

def method_missing(method_name, *args, &block)
  begin
    invoke_query_api_pattern_method(method_name, *args, &block)
  rescue PatternNotFoundError
    super
  end
end

Class Method Details

.included(base) ⇒ void

This method returns an undefined value.

Standard included

Examples:

# no example


42
43
44
# File 'lib/base/helpers/query_api_patterns.rb', line 42

def self.included(base)
  base.extend(ClassMethods)
end

Instance Method Details

#compute_query_api_pattern_array_data(query_api_method_name, source, params_with_defaults, used_query_params) ⇒ Array

Parses Array objects

Returns:



809
810
811
812
813
814
815
816
# File 'lib/base/helpers/query_api_patterns.rb', line 809

def compute_query_api_pattern_array_data(query_api_method_name, source, params_with_defaults, used_query_params)
  result = source.dup
  source.dup.each_with_index do |item, idx|
    value = compute_query_api_pattern_param(query_api_method_name, item, params_with_defaults, used_query_params)
    value == Utils::NONE ? result.delete_at(idx) : result[idx] = value
  end
  result
end

#compute_query_api_pattern_param(query_api_method_name, source, params_with_defaults, used_query_params) ⇒ Object

Computes single Query API pattern parameter

Examples:

# no example

Parameters:

  • query_api_method_name (String)

    Auery API like pattern name.

  • source (Hash)

    The param to compute/parse.

  • used_query_params (Hash)

    The list of used variables.

  • params_with_defaults (Hash)

    The set of parameters passed by a user + all the default values defined in wrappers.

Returns:



495
496
497
498
499
500
501
502
503
# File 'lib/base/helpers/query_api_patterns.rb', line 495

def compute_query_api_pattern_param(query_api_method_name, source, params_with_defaults, used_query_params) # :nodoc:
  case
  when source.is_a?(Hash)   then compute_query_api_pattern_hash_data(query_api_method_name, source, params_with_defaults, used_query_params)
  when source.is_a?(Array)  then compute_query_api_pattern_array_data(query_api_method_name, source, params_with_defaults, used_query_params)
  when source.is_a?(Symbol) then compute_query_api_pattern_symbol_data(query_api_method_name, source, params_with_defaults, used_query_params)
  when source.is_a?(String) then compute_query_api_pattern_string_data(query_api_method_name, source, params_with_defaults, used_query_params)
  else                           source
  end
end

#compute_query_api_pattern_string_data(query_api_method_name, source, params_with_defaults, used_query_params) ⇒ String

Parses String objects

Returns:

Raises:



829
830
831
832
833
834
835
836
837
838
# File 'lib/base/helpers/query_api_patterns.rb', line 829

def compute_query_api_pattern_string_data(query_api_method_name, source, params_with_defaults, used_query_params)
  result = source.dup
  result.scan(FIND_KEY_REGEXP).flatten.each do |key|
    fail Error::new("#{query_api_method_name}: #{key.inspect} is required") unless params_with_defaults.has_key?(key)
    value = params_with_defaults[key]
    result.gsub!("{:#{key}}", value == Utils::NONE ? '' : value.to_s)
    used_query_params << key
  end
  result
end

#compute_query_api_pattern_symbol_data(query_api_method_name, source, params_with_defaults, used_query_params) ⇒ String

Parses Symbol objects

Returns:

Raises:



851
852
853
854
855
856
857
# File 'lib/base/helpers/query_api_patterns.rb', line 851

def compute_query_api_pattern_symbol_data(query_api_method_name, source, params_with_defaults, used_query_params)
  key = source.to_s
  fail Error::new("#{query_api_method_name}: #{key.inspect} is required") unless params_with_defaults.has_key?(key)
  result = params_with_defaults[key]
  used_query_params << key
  result
end

#explain_query_api_pattern(pattern_name) ⇒ Stringq

Explains the given pattern by name

(Displays the pattern definition)

Examples:

puts open_stack.explain_query_api_pattern('AttachVolume') #=>
   AttachVolume: POST 'servers/{:id}/os-volume_attachments'
     - body    :  {:volumeAttachment=>{"volumeId"=>:volumeId, "device"=>:device}}

Parameters:

  • pattern_name (String)

    The pattern method name.

Returns:

  • (Stringq)


230
231
232
233
234
235
236
237
238
239
240
241
242
243
# File 'lib/base/helpers/query_api_patterns.rb', line 230

def explain_query_api_pattern(pattern_name)
  pattern_name = pattern_name.to_s
  result       = "#{pattern_name}: "
  pattern      = query_api_patterns[pattern_name]
  unless pattern
    result << 'does not exist'
  else
    result << "#{pattern[:verb].to_s.upcase} '#{pattern[:path]}'"
    [:params, :headers, :options, :body, :before, :after].each do |key|
      result << ("\n  - %-8s:  #{pattern[key].inspect}" % key.to_s) unless pattern[key]._blank?
    end
  end
  result
end

#invoke_query_api_pattern_method(method_name, *args, &block) ⇒ Object

Execute pattered method if it exists

Examples:

# no example

Returns:

Raises:



313
314
315
316
317
318
319
320
321
# File 'lib/base/helpers/query_api_patterns.rb', line 313

def invoke_query_api_pattern_method(method_name, *args, &block)
  computed_data = compute_query_api_pattern_based_params(method_name, args.first)
  # Make an API call:
  __send__(computed_data[:method],
           computed_data[:verb],
           computed_data[:path],
           computed_data[:opts],
           &block)
end

#query_api_pattern(method_name, verb, path = '', opts = {}, &block) ⇒ void

This method returns an undefined value.

Set object specific QUERY-like pattern

This guy is usually called from Wrapper’s module from self.extended method (see S3 default wrapper)

Examples:

# no example


254
255
256
# File 'lib/base/helpers/query_api_patterns.rb', line 254

def query_api_pattern(method_name, verb, path='', opts={}, &block)
  self.class.query_api_pattern(method_name, verb, path, opts, @query_api_patterns, &block)
end

#query_api_patternsArray

Returns the list of current patterns

The patterns can be defined at the class levels or/and in special Wrapper modules. The patterns defined at the class levels are always inherited by the instances of this class, when the wrapper defined patterns are applied to this particular object only.

This allows one to define generic patterns at the class level and somehow specific at the level of wrappers.

P.S. The method is usually called in Wrapper modules (see S3 default wrapper)

Examples:

# no example

Returns:

  • (Array)

    The has of QUERY-like method patterns.



211
212
213
214
215
# File 'lib/base/helpers/query_api_patterns.rb', line 211

def query_api_patterns
  @query_api_patterns ||= {}
  # The current set of patterns may override whatever is defined at the class level.
  self.class.query_api_patterns.merge(@query_api_patterns)
end