Class: Lorj::BaseDefinition

Inherits:
Object show all
Defined in:
lib/core/definition.rb,
lib/core/definition.rb,
lib/core/definition.rb,
lib/core/definition.rb,
lib/core/definition.rb,
lib/core/core_process.rb,
lib/core/core_process.rb,
lib/core/core_setup_ask.rb,
lib/core/core_controller.rb,
lib/core/core_setup_init.rb,
lib/core/core_setup_list.rb,
lib/core/core_import_export.rb,
lib/core/core_object_params.rb,
lib/core/core_process_setup.rb,
lib/core/core_setup_encrypt.rb,
lib/core/definition_internal.rb,
lib/core/lorj_basedefinition.rb

Overview

Following class defines class levels function to declare framework objects. As each process needs to define new object to deal with require that process to define it with definition functions See definition.rb for functions to use.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(oForjConfig, process, controller = nil) ⇒ BaseDefinition

Initialize Lorj BaseDefinition object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/core/lorj_basedefinition.rb', line 28

def initialize(oForjConfig, process, controller = nil)
  # Object Data object. Contains all loaded object data.
  # This object is used to build hParams as well.
  @object_data = ObjectData.new(true)
  #
  @runtime_context = {
    :oCurrentObj => nil
  }

  @config = oForjConfig

  @data = Lorj.data # Get data definition object
  # data object is currently built by
  # - global application defaults.yaml loaded in @config.
  # - process data.yaml files

  @erb_config = ERBConfig.new(oForjConfig)
  if !oForjConfig.is_a?(Lorj::Account) && !oForjConfig.is_a?(Lorj::Config)
    PrcLib.runtime_fail "'%s' is not a valid ForjAccount or ForjConfig"\
                       ' Object.', oForjConfig.class
  end
  @controller = controller
  unless controller.nil? || controller.is_a?(BaseController)
    PrcLib.runtime_fail "'%s' is not a valid BaseController Object type.",
                        controller.class
  end

  @process = process
  PrcLib.runtime_fail "'%s' is not a valid BaseProcess Object type.",
                      process.class unless process.is_a?(BaseProcess)

  @process.base_object = self
end

Instance Attribute Details

#obj_type=(value) ⇒ Object (writeonly)

Sets the attribute obj_type



350
351
352
# File 'lib/core/definition.rb', line 350

def obj_type=(value)
  @obj_type = value
end

Class Method Details

._configure_options_handlers(options) ⇒ Object

Internal function



587
588
589
590
591
# File 'lib/core/definition.rb', line 587

def self._configure_options_handlers(options)
  for_events = PrcLib.model.meta_obj.rh_get(PrcLib.model.object_context,
                                            :lambdas).keys
  options.merge(:for => for_events) unless options.key?(:for)
end

._decl_data_valid?(value, map) ⇒ Boolean

Internal model data validation return true if valid. false otherwise.



540
541
542
543
544
# File 'lib/core/definition.rb', line 540

def self._decl_data_valid?(value, map)
  return false unless [String, Symbol].include?(value.class)
  return false unless [NilClass, Symbol, String].include?(map.class)
  true
end

._decl_object_attr_valid?(key, map, options) ⇒ Boolean

Internal model data validation return true if valid. false otherwise.



530
531
532
533
534
535
536
# File 'lib/core/definition.rb', line 530

def self._decl_object_attr_valid?(key, map, options)
  return false unless [String, Symbol].include?(key.class)
  return false unless options.is_a?(Hash)
  return false unless [Symbol, String, Array].include?(map.class)

  true
end

._define_obj_initialize(obj_type_name, handlers) ⇒ Object

Internal function



627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# File 'lib/core/definition.rb', line 627

def self._define_obj_initialize(obj_type_name, handlers)
  use_controller = PrcLib.model[:use_controller]

  if use_controller.nil?
    PrcLib.model.options :use_controller => true
    use_controller = true
  end

  # TODO: Cleanup un-used 2 levels :params/:keys by single :params
  object = { :lambdas => { :create_e => nil, :delete_e => nil,
                           :update_e => nil, :get_e => nil,
                           :query_e => nil, :get_attr_e => nil,
                           :refresh_e => nil },
             :params =>  { :keys => {} },
             :options => { :controller => use_controller },
             :query_mapping => { ':id' => ':id', ':name' => ':name' },
             :returns => { ':id' => ':id', ':name' => ':name' }
           }

  PrcLib.dcl_fail("A new declared object '%s' requires at "\
                  'least one handler. Ex: define_obj :%s, '\
                  'create_e: myhandler or nohandler: true',
                  obj_type_name,
                  obj_type_name) if handlers.length == 0

  if !handlers.rh_get(:nohandler)
    msg = '%-28s object declared.'
  else
    msg = '%-28s meta object declared.'
  end
  Lorj.debug(2, msg, _object_name(obj_type_name))
  object
end

._define_object_needs(params, type, msg_action, options) ⇒ Object

Internal function



571
572
573
574
575
576
577
578
579
580
581
582
583
584
# File 'lib/core/definition.rb', line 571

def self._define_object_needs(params, type, msg_action, options)
  attribute = PrcLib.model.attribute_context

  case type
  when :data
    return _obj_needs_data(params[:keys][attribute.fpath],
                           msg_action, options)
  when :CloudObject, :object
    return _obj_needs_object(params[:keys][attribute.fpath],
                             options)
  end
  PrcLib.dcl_fail("%s: Object parameter type '%s' unknown.",
                  self.class, type)
end

._handler_settings(object, handlers_options) ⇒ Object

Setting procs



687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
# File 'lib/core/definition.rb', line 687

def self._handler_settings(object, handlers_options)
  handlers_dcl = object[:lambdas]
  process_context = PrcLib.model.process_context

  handlers_dcl.each_key do |key|
    next unless handlers_options.key?(key)

    # Warning! Use BaseProcess._instance_methods Compatibility function
    # instead of BaseProcess.instance_methods
    unless process_context._instance_methods.include?(handlers_options[key])
      PrcLib.dcl_fail("'%s' parameter requires a valid instance method"\
                      " '%s' in the process '%s'.",
                      key, handlers_options[key], process_context)
    end
    if handlers_options[key] == :default
      # By default, we use the event name as default function to call.
      # Those function are predefined in ForjController
      # The Provider needs to derive from ForjController and redefine those
      # functions.
      object[:lambdas][key] = key
    else
      # If needed, ForjProviver redefined can contains some additionnal
      # functions to call.
      object[:lambdas][key] = handlers_options[key]
    end
  end
end

._initialize_object_needs(name) ⇒ Object

Internal function for obj_needs Initialize :params/:keys/



555
556
557
558
559
560
561
562
563
564
565
566
567
568
# File 'lib/core/definition.rb', line 555

def self._initialize_object_needs(name)
  top_param_obj = PrcLib.model.meta_obj.rh_get(PrcLib.model.object_context,
                                               :params)

  PrcLib.model.attribute_context KeyPath.new(name)
  key_access = PrcLib.model.attribute_context.fpath

  unless top_param_obj[:keys].key?(key_access)
    top_param_obj[:keys][key_access] = {}
    return 'New'
  end

  'Upd'
end

._obj_needs_data(object_attr, msg_action, new_params) ⇒ Object

Internal function



598
599
600
601
602
603
604
605
606
607
608
609
610
611
# File 'lib/core/definition.rb', line 598

def self._obj_needs_data(object_attr, msg_action, new_params)
  attr_name = PrcLib.model.attribute_context
  if Lorj.data.auto_meta_exist?(attr_name)
    Lorj.debug(2, "%-28s: %s predefined config '%s'.",
               _object_name(PrcLib.model.object_context),
               msg_action, attr_name)
  else
    Lorj.debug(2, "%-28s: %s runtime    config '%s'.",
               _object_name(PrcLib.model.object_context),
               msg_action, attr_name)
  end
  # Merge from predefined params, but ensure type is never updated.
  object_attr.merge!(new_params.merge(:type => :data))
end

._obj_needs_object(object_attr, new_params) ⇒ Object

Internal function



614
615
616
617
618
619
620
621
622
623
624
# File 'lib/core/definition.rb', line 614

def self._obj_needs_object(object_attr, new_params)
  attr_name = PrcLib.model.attribute_context
  unless PrcLib.model.meta_obj.key?(attr_name.key)
    PrcLib.dcl_fail("%s: '%s' not declared. Missing define_obj(%s)?",
                    self.class,
                    attr_name,
                    attr_name)
  end
  # Merge from predefined params, but ensure type is never updated.
  object_attr.merge!(new_params.merge(:type => :CloudObject))
end

._object_name(name) ⇒ Object

Internal function to get the object_name as class.object

return formated string.



549
550
551
# File 'lib/core/definition.rb', line 549

def self._object_name(name)
  format("'%s.%s'", self.class, name)
end

._query_mapping(key, map) ⇒ Object

Internal function



482
483
484
485
486
487
488
489
490
491
492
493
494
# File 'lib/core/definition.rb', line 482

def self._query_mapping(key, map)
  return nil unless [String, Symbol].include?(key.class)
  return nil unless [NilClass, Symbol, String, Array].include?(map.class)

  object_type = PrcLib.model.object_context
  key_path = KeyPath.new(key)
  map_path_obj = KeyPath.new(map)

  PrcLib.model.attribute_context key_path

  PrcLib.model.meta_obj.rh_set(map_path_obj.fpath, object_type,
                               :query_mapping, key_path.fpath)
end

._section_from(data) ⇒ Object

Internal section detection based on a keyPath Object



520
521
522
523
524
525
526
# File 'lib/core/definition.rb', line 520

def self._section_from(data)
  return data.key[0] if data.length == 2
  section = Lorj.defaults.get_meta_section(data.key)
  section = :runtime if section.nil?

  section
end

._set_attr_mapping(key, map, options) ⇒ Object

Internal function to store object attribute and mapping information parameters:

  • key : KeyPath. key object

  • map : KeyPath. map object

  • options: Hash. Options to set.



501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/core/definition.rb', line 501

def self._set_attr_mapping(key, map, options)
  return nil unless _decl_object_attr_valid?(key, map, options)

  object_type = PrcLib.model.object_context
  key_path_obj = KeyPath.new(key)

  map_path_obj = KeyPath.new(map)

  PrcLib.model.meta_obj.rh_set(map_path_obj.fpath, object_type,
                               :returns, key_path_obj.fpath)

  PrcLib.model.attribute_context key_path_obj

  return if options[:not_queriable] == true
  query_mapping(key, map)
  [key_path_obj.fpath, map_path_obj.fpath]
end

._verify_handlers(type_name, object, handlers) ⇒ Object

Internal function for define_obj Check handler options. Return the list of handlers set if handler list is ok (exist 1 at least) return false if no handler is set.



665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
# File 'lib/core/definition.rb', line 665

def self._verify_handlers(type_name, object, handlers)
  return false if handlers.rh_get(:nohandler)

  PrcLib.dcl_fail("A new declared object '%s' requires at "\
                  'least one handler. Ex: define_obj :%s, '\
                  'create_e: myhandler or nohandler: true',
                  type_name, type_name) if object.nil? &&
                                           handlers.length == 0

  return handlers if object.nil?

  handlers_list = object[:lambdas].keys.join(', ')
  handlers.each_key do |key|
    next if object.rh_exist?(:lambdas, key)

    PrcLib.dcl_fail("'%s' parameter is invalid. Use '%s'",
                    key, handlers_list)
  end
  handlers
end

.attr_value_mapping(value, map) ⇒ Object

Controller to declare an lorj object attribute data mapping.

You need to define object and attribute context before attr_value_mapping

parameters:

  • value : name of the default object attribute

  • map : Map a predefined object attribute value.

Ex: If the application model has defined:

   :server[:status] = [:create, :boot, :active]

define_obj :server # Required to set object context
get_attr_mapping :status, :state # set attribute mapping and context.
attr_value_mapping :create, 'BUILD'
attr_value_mapping :boot,   :boot
attr_value_mapping :active, 'ACTIVE'


395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
# File 'lib/core/definition.rb', line 395

def self.attr_value_mapping(value, map)
  PrcLib.model.heap true

  return nil unless _decl_data_valid?(value, map)

  object_type = PrcLib.model.object_context

  key_path = PrcLib.model.attribute_context __callee__

  keypath = key_path.fpath
  Lorj.debug(2, "%s-%s: Attribute value mapping '%s' => '%s'",
             object_type, key_path.to_s, value, map)
  PrcLib.model.meta_obj.rh_set(map,
                               object_type, :value_mapping, keypath, value)
end

.current_process(cProcessClass) ⇒ Object

Process declaration Defines current Process context

parameters:

  • process_class : Process Class object.



36
37
38
39
# File 'lib/core/definition.rb', line 36

def self.current_process(cProcessClass)
  PrcLib.model.heap true
  PrcLib.model.process_context(cProcessClass)
end

.data_value_mapping(value, map) ⇒ Object

Controller to declare a model Data value mapping

Parameters:

  • value : Value to map

  • map : Value mapped



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
# File 'lib/core/definition.rb', line 301

def self.data_value_mapping(value, map)
  return nil unless _decl_data_valid?(value, map)
  PrcLib.model.heap true

  data = PrcLib.model.data_context

  section = _section_from(data)

  Lorj.debug(2, format("%s/%s: Define config data value mapping: '%s' => "\
                       "'%s'", section, data.fpath, value, map))
  PrcLib.model..rh_set(map, section, data,
                                :value_mapping,  :controller, value)
  PrcLib.model..rh_set(value, section, data,
                                :value_mapping,  :process, map)
end

.def_attr_mapping(key, map, options = {}) ⇒ Object

Function used by the controler to define mapping. By default, any attributes are queriable as well. No need to call query_mapping

parameters:

  • key : name of the default object attribute

  • map : optional.

  • options: optional.



370
371
372
373
374
375
376
# File 'lib/core/definition.rb', line 370

def self.def_attr_mapping(key, map, options = {})
  PrcLib.model.heap true
  key_paths = _set_attr_mapping(key, map, options)

  Lorj.debug(4, "%s: Defining object attribute mapping '%s' => '%s'",
             PrcLib.model.object_context, key_paths[0], key_paths[1])
end

.def_attribute(key, options = {}) ⇒ Object

Function used by the Process to define Model Object attributes. By default, any attributes are queriable as well. No need to call query_mapping

parameters:

  • key : name of the default object attribute

  • options: optional.



233
234
235
236
237
238
239
240
# File 'lib/core/definition.rb', line 233

def self.def_attribute(key, options = {})
  PrcLib.model.heap true

  key_path = _set_attr_mapping(key, key, options)[0]

  Lorj.debug(4, "%s: Defining object attribute '%s'",
             PrcLib.model.object_context, key_path)
end

.def_hdata(attr_name, options = {}) ⇒ Object

Controller to declare predefined Hash options for controller wrapper code.

When a controller wrapper code is called to execute a function, the controller may/should provides some options.

lorj framework can simplify the way to call this function and provide a predefined options list, prepared by lorj.

Ex: If you are calling a connection function, which requires one

or more parameters passed as an Hash:

wrapper code without using :hdata:

def connect(params)
   options = { :hp_access_key => params[:account_id],
               :hp_secret_key => params[:account_key]
               :hp_auth_uri => params[:auth_uri]
               :hp_tenant_id => params[:tenant]
               :hp_avl_zone => params[:network]
   }
   Fog::HP::Network.new(options)
end

wrapper code using :hdata and def_hdata:

def connect(params)
   Fog::HP::Network.new(params[:hdata])
end

def_hdata requires the object context. Ex:

define_obj(:student)
def_hdata :first_name
def_hdata :last_name
def_hdata :course,      mapping: :training

parameters:

  • attr_name : Attribute name to add in :hdata Hash

    as hdata[attr_name] = value.
    
  • options: Possible options:

    • :mapping : map name to use mapping instead of attr_name.

      hdata[map_name] = value
      


452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
# File 'lib/core/definition.rb', line 452

def self.def_hdata(attr_name, options = {})
  PrcLib.model.heap true
  fct_context = { :function_name => __callee__ }
  return nil unless [String, Symbol, Array].include?(attr_name.class)

  options = {} unless options.is_a?(Hash)

  object_type = PrcLib.model.object_context(fct_context)

  key_access = KeyPath.new(attr_name).fpath

  # PrcLib.model.meta_obj://<Object>/:params/:keys/<keypath> must exist.
  object_param = PrcLib.model.meta_obj.rh_get(object_type,
                                              :params, :keys, key_access)

  object_param[:mapping] = attr_name
  object_param[:mapping] = options[:mapping] unless options[:mapping].nil?

  Lorj.debug(2, "%-28s: hdata set '%s' => '%s'",
             _object_name(object_type), attr_name, object_param[:mapping])

  # Internally, lorj stores this declaration in
  # PrcLib.model.meta_obj://<Object>/:params/:keys/<keypath>/:mapping)
end

.def_query_attribute(key) ⇒ Object

Application process to defines query attributes.

This function is depreciated.

def_attribute or def_attr_mapping already set the attribute as queriable. If the controller needs to redefine how the attribute is queried, use it will needs to call query_mapping.

But from process point of view, all attribute must be queriable.

So, use def_attribute(process), then query_mapping(controller)



165
166
167
168
# File 'lib/core/definition.rb', line 165

def self.def_query_attribute(key)
  PrcLib.model.heap true
  query_mapping(key, key)
end

.define_data(data, options) ⇒ Object

Process or controller to defines or update data model options Possible data model options are defined definition under <section>/<data> of defaults.yaml

Parameters:

  • data : String/Symbol. Name of the data

  • options : Hash. List of options



279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/core/definition.rb', line 279

def self.define_data(data, options)
  return nil unless [String, Symbol].include?(data.class)
  return nil if options.class != Hash
  PrcLib.model.heap true

  data = KeyPath.new data, 2
  PrcLib.dcl_fail("%s: Config data '%s' unknown",
                  self.class,
                  data) unless Lorj.data.auto_meta_exist?(data.key)

  PrcLib.model.data_context data

  section, key = Lorj.data.first_section(data.key)

  Lorj.data.define_controller_data(section, key, options)
end

.define_obj(obj_type_name, handlers = nil) ⇒ Object

Application process or controller to defines an object.

The context will be set by this definition for next declaration. Depending on the context, define_obj is not used identically:

Context : Application Process ‘define_obj’ is the first object declaration. It sets the object context for next declaration. At least it needs to create an handler or define it with :nohandler: true

Usually, this definition is followed by:

  • def_attribute : Object attribute list

  • obj_needs : Handler parameters needs

  • undefine_attribute : Remove predefined attributes.

  • def_query_attribute: Query attribute definition

Context: Controller

A controller uses define_obj to update an existing object. A controller can create a new object, only if the controller defines specific process.

Usually, this definition is followed by:

  • query_mapping : Adapt query attribute to match controller query

    settings
    
  • obj_needs : Adapt needed parameters, and/or set mapping.

  • def_hdata : Define Controller Hash parameter, for handlers.

  • def_attr_mapping : Define object attribute mapping.

  • data_value_mapping: Define Data model values mapping.

  • Args

    • type : Symbol. Object type to declare.

    • handlers : Hash. List of Process handler to call for create/query/get/delete/update/get_attr. Handlers supported:

      • :create_e : Process function to call with create

      • :delete_e : Process function to call with delete

      • :update_e : Process function to call with update

      • :get_e : Process function to call with get

      • :query_e : Process function to call with query

      • :get_attr_e : Process function to call with get_attr

      • :refresh_e : Process function to call with refresh



129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
# File 'lib/core/definition.rb', line 129

def self.define_obj(obj_type_name, handlers = nil)
  return nil unless [NilClass, String, Symbol].include?(obj_type_name.class)
  PrcLib.model.heap true

  obj_type_name = obj_type_name.to_sym if obj_type_name.is_a?(String)

  handlers = {} unless handlers.is_a?(Hash)

  lorj_object = PrcLib.model.meta_obj.rh_get(obj_type_name)

  # Checking handlers_options data
  _verify_handlers(obj_type_name, lorj_object, handlers)

  if lorj_object.nil?
    lorj_object = _define_obj_initialize(obj_type_name, handlers)
    PrcLib.model.meta_obj.rh_set(lorj_object, obj_type_name)
  end

  PrcLib.model.object_context(:object => obj_type_name)

  _handler_settings(lorj_object, handlers)

  nil
end

.defined?(objType) ⇒ Boolean



317
318
319
320
# File 'lib/core/definition.rb', line 317

def self.defined?(objType)
  PrcLib.model.heap true
  @obj_type.include?(objType)
end

.obj_needs(type, name, options = {}) ⇒ Object

Function to declare handlers data/object needs. Used by application process declaration and controller declaration to defines the object data needs or sub-object dependency.

The application process declare global objects/data dependency while the controller can complete it with any needed other object/data as required by the controller code.

Ex: A process can define a generic connection object.

define_obj :connection
obj_needs :data, :user,   :for => [:create_e]
obj_needs :data, :passwd, :for => [:create_e]

The controller can add several other needs, specifically
to this controller.

define_obj :connection
obj_needs :data, :user,   mapping => :username
obj_needs :data, :uri

Requires Object context

parameters:

  • type : :data or :object requirement

  • name : Name of the data or the object.

  • options : Possible options

    • :for : Array: requirement for a limited list of handler.

      By default, all handlers requires this data or object.
      


204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
# File 'lib/core/definition.rb', line 204

def self.obj_needs(type, name, options = {})
  return nil unless [String, Symbol].include?(type.class)
  return nil unless [String, Symbol, Array].include?(name.class)
  PrcLib.model.heap true

  type = type.to_sym if type.is_a?(String)

  options = {} unless options.is_a?(Hash)

  unless options.key?(:required)
    options[:required] = !PrcLib.model.needs_optional
  end

  _configure_options_handlers(options)

  params = PrcLib.model.meta_obj.rh_get(PrcLib.model.object_context,
                                        :params)

  _define_object_needs(params, type,
                       _initialize_object_needs(name), options)
end

.obj_needs_optionalObject

Process declaration Set obj_needs requirement setting to false



44
45
46
47
# File 'lib/core/definition.rb', line 44

def self.obj_needs_optional
  PrcLib.model.heap true
  PrcLib.model.needs_optional true
end

.obj_needs_requiresObject

Process declaration Set obj_needs requirement setting to True



52
53
54
55
# File 'lib/core/definition.rb', line 52

def self.obj_needs_requires
  PrcLib.model.heap true
  PrcLib.model.needs_optional false
end

.predefine_data_value(data, hOptions) ⇒ Object

Internal BaseDefinition function



324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
# File 'lib/core/definition.rb', line 324

def self.predefine_data_value(data, hOptions)
  PrcLib.model.heap true
  # Refuse to run if not a
  return nil if self.class != BaseDefinition
  # BaseDefinition call
  return nil unless [String, Symbol].include?(value.class)
  return nil unless [NilClass, Symbol, String].include?(map.class)

  key_path = PrcLib.model.attribute_context

  value = { data => { :options => hOptions } }

  PrcLib.model.predefine_data_value.rh_set(value,
                                           key_path.fpath, :values)
end

.process_default(hOptions) ⇒ Object

Process declaration Defines default process options

parameters:

  • options : Supported options are:

    • use_controller : Boolean. True if the model require a controller

      False otherwise. Default is true.
      


65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/core/definition.rb', line 65

def self.process_default(hOptions)
  PrcLib.model.heap true
  supported_options = [:use_controller]
  unless hOptions.nil?
    hOptions.each_key do |key|
      case key
      when :use_controller
        value = hOptions.rh_get(:use_controller)
        next unless value.boolean?
        PrcLib.model[key] = hOptions[key]
      else
        PrcLib.dcl_fail("Unknown default process options '%s'. "\
                        "Supported are '%s'",
                        key, supported_options.join(','))
      end
    end
  end
end

.query_mapping(key, map) ⇒ Object

Controller declaration to map an query attribute By default, def_attribute configure those attributes as queriable. The controller can redefine the query part. Use def_attribute or def_attr_mapping All attributes are considered as queriable.



357
358
359
360
# File 'lib/core/definition.rb', line 357

def self.query_mapping(key, map)
  PrcLib.model.heap true
  _query_mapping(key, map)
end

.undefine_attribute(key) ⇒ Object

Process to undeclare default lorj object attributes By default, while process declares a new lorj object, :id and :name are predefined. If the model of this lorj object do not have any ID or Name the process will needs to undeclare it.

The Controller can undeclare some attribute defined by the Application process model. But it requires the controller to re-define any object handler which can use those attributes.

parameters:

  • key : Attribute name to undeclare.



254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/core/definition.rb', line 254

def self.undefine_attribute(key)
  return nil unless [String, Symbol].include?(key.class)
  PrcLib.model.heap true

  PrcLib.dcl_fail('%s: No Object defined. Missing define_obj?',
                  self.class) if PrcLib.model.object_context.nil?

  key_path = KeyPath.new(key)

  PrcLib.model.meta_obj.rh_set(nil, PrcLib.model.object_context,
                               :returns, key_path.fpath)
  PrcLib.model.attribute_context key_path
  Lorj.debug(4, "%s: Undefining attribute mapping '%s'",
             PrcLib.model.object_context, key_path.fpath)

  _query_mapping(key, nil)
end

Instance Method Details

#_ask(sDesc, default, rValidate, bEncrypted, bRequired) ⇒ Object

internal runtime function for process call Ask function executed by setup

parameters:

- +sDesc+       : data description
- +default+     : default value
- +rValidate+   : RegEx to validate the end user input.
- +bEncrypted+  : Encrypt data
- +bRequired+   : true if a value is required.

return:

  • value : value or encrypted value.

raise:



310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/core/core_setup_ask.rb', line 310

def _ask(sDesc, default, rValidate, bEncrypted, bRequired)
  value = nil
  loop do
    if bEncrypted
      value = _ask_encrypted(sDesc, default)
    else
      value = ask(format('Enter %s:', sDesc)) do |q|
        q.default = default unless default.nil?
        q.validate = rValidate unless rValidate.nil?
      end
    end
    break unless bRequired && value == ''
    say ANSI.bold('This information is required!')
  end
  value.to_s
end

#_nil_if_no_value(value) ⇒ Object

Internal function to return nil if value is empty.



328
329
330
331
# File 'lib/core/core_setup_ask.rb', line 328

def _nil_if_no_value(value)
  return nil if value.nil? || value == ''
  value
end

#_query_map(object_type, hParams) ⇒ Object

Before doing a query, mapping fields Transform Object query field to Provider query Fields



103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/core/lorj_basedefinition.rb', line 103

def _query_map(object_type, hParams)
  return {} unless hParams

  object_type = object_type.to_sym if object_type.class == String

  result = {}
  maps = PrcLib.model.meta_obj.rh_get(object_type, :query_mapping)
  hParams.each do |key, value|
    key_path_obj = KeyPath.new(key)

    bold_action = ANSI.bold('ACTION REQUIRED')
    PrcLib.runtime_fail "Forj query field '%s.%s' not defined by class"\
                        " '%s'.\n#{bold_action}"\
                        ":\nMissing data model 'def_attribute' or "\
                        "'def_query_attribute' for '%s'??? "\
                        "Check the object '%s' data model.",
                        object_type, key_path_obj.key,
                        self.class, key_path_obj.key,
                        object_type unless maps.key?(key_path_obj.fpath)

    next if maps[key_path_obj.fpath].nil?

    map_path = KeyPath.new(maps[key_path_obj.fpath])
    _query_value_mapping(object_type, result, key_path_obj, map_path, value)
  end
  result
end

#_query_value_mapping(object_type, result, key_path_obj, map_path, value) ⇒ Object



131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/core/lorj_basedefinition.rb', line 131

def _query_value_mapping(object_type, result, key_path_obj, map_path, value)
  key_path = key_path_obj.fpath
  value_mapping = PrcLib.model.meta_obj.rh_get(object_type, :value_mapping,
                                               key_path)
  if value_mapping
    PrcLib.runtime_fail "'%s.%s': No value mapping for '%s'",
                        object_type, key_path_obj.key,
                        value unless value_mapping.rh_exist?(value)

    result.rh_set(value_mapping[value], map_path.to_s)
  else
    result.rh_set(value, map_path.to_s)
  end
  nil
end

#_setup_ask(setup_steps) ⇒ Object

internal setup core function which ask user to enter values. looping step by step and presenting sorted data to set.

It execute pre-process if defined by: /:section/<section name>/<data>/:pre_step_function

If pre-process returns true, end user interaction is canceled.

  • Args :

  • setup_steps : setup data structure.

  • Returns:

  • Raises :



1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
# File 'lib/core/core_setup_init.rb', line 1076

def _setup_ask(setup_steps)
  # Ask for user input
  # TODO: Enhance to support section::data to avoid duplicated data name
  #   against sections.
  setup_steps.each_index do |iStep|
    _setup_display_step(setup_steps[iStep], iStep)

    order_array = setup_steps[iStep][:order]

    order_array.each_key do |iIndex|
      Lorj.debug(2, 'Ask order %s:', iIndex)
      order_array[iIndex].each do |data|
        options = (data)
        options = {} if options.nil?

        Lorj.data.layer_add(:name => :setup)

        if options[:pre_step_function]
          proc = options[:pre_step_function]
          next unless @process.method(proc).call(data)
          # Get any update from pre_step_function
          options = (data)
        end

        data_desc = _setup_display_data(data, options)

        _setup_ask_data(data_desc, data, options)

        Lorj.data.layer_remove(:name => :setup)
      end
    end
  end
end

#_setup_ask_data(desc, data, options) ⇒ Object

Internal setup function to ask to the end user. It execute post-process if defined by: /:section/<section name>/<data>/:post_step_function

if post-process returns false, the user is requested to re-enter a new value

  • Args :

    • desc : Data description

    • data : Data to ask.

    • options: list and validation options

      • :post_step_function : Call a post process function.

  • Returns:

    • nothing

  • Raises :



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/core/core_setup_ask.rb', line 47

def _setup_ask_data(desc, data, options)
  loop do
    if options[:list_values].nil?
      value = _setup_ask_data_from_keyboard(desc, data, options)
    else
      value = _setup_ask_data_from_list(data, options[:list_values],
                                        desc, options)
    end

    # @config.set(data, value) ??? Why do we need that???
    section = (data)
    # We set the value only if there is a value entered by the user.
    unless section.nil? || value.nil?
      Lorj.debug(3, "'%s'/'%s': Setting value to '%s'",
                 section, data, value)
      @config.set(data, value, :name => 'account', :section => section)
    end

    result = _setup_ask_post_process(options[:post_step_function])
    break unless result.is_a?(FalseClass)
  end
end

#_setup_ask_data_from_keyboard(desc, data, options, default = nil) ⇒ Object

Internal setup function to ask to the end user.

  • Args :

    • desc : Data description

    • data : Data to ask.

    • options: list and validation options

      • :ask_function : Replace the _ask default call by a process function This function should return a string or nil, if no value.

      • :default_value: Predefined default value.

    • default: Default value.

      setup will present a default value. This value can come from several places, as follow in that order:

      1. if a value is found from config layers => choose it as default

      2. if default parameter is not nil => choose it as default

      3. if data model defines :default_value. => choose it

      In this last case, the :default_value is interpreted by ERB.
      ERB context contains:
      - config : data config layer.
      
      Ex: So you can set :default_value like:
      
           :default_value: "~/.ssh/<%= config[:keypair_name] %>-id_rsa"
      This may assume that keypair_name is setup before abd would need:
      - :after: <datas>
      
  • Returns:

    • value : value entered by the end user or nil if no value.

  • Raises :



261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
# File 'lib/core/core_setup_ask.rb', line 261

def _setup_ask_data_from_keyboard(desc, data, options, default = nil)
  valid_regex = nil
  valid_regex = options[:validate] unless options[:validate].nil?

  is_required = (options[:required] == true)
  is_encrypted = options[:encrypted]

  if default.nil? && !options[:default_value].nil?
    begin
      default = erb(options[:default_value])
      Lorj.debug(3, "'%s': Running ERB for default_value '%s' = '%s'",
                 data, options[:default_value], default)
    rescue => e
      PrcLib.warning("ERB error with :%s/:default_value '%s'.\n%s",
                     data, options[:default_value], e.message)
    end
  end
  ask_default = @config.get(data, default)
  Lorj.debug(3, "'%s': Getting value from config - '%s'(from '%s' - "\
                "sections '%s') (default is '%s')",
             data, ask_default, @config.where?(data),
             Lorj.data.sections(data), default)

  # validate_proc = options[:validate_function]
  proc_ask = options[:ask_function]

  if proc_ask.nil?
    value = _ask(desc, ask_default, valid_regex, is_encrypted, is_required)
  else
    value = @process.method(proc_ask)
  end
  _nil_if_no_value(value)
end

#_setup_ask_data_from_list(data, list_options, desc, options) ⇒ Object

Internal setup function to ask to the end user from a list.

  • Args :

  • data : Data to ask.

  • list_options: list and validation options

    • :validate : Can be :list_strict to restrict possible value to only those listed.

  • desc : Data description

  • options : Used when user have to enter a string instead of

    selecting from a list.
    
    • :default_value : predefined default value.

    if data model defines :default_value. => choose it
    In this last case, the :default_value is interpreted by ERB.
    ERB context contains:
      - config : data config layer.
    
      Ex: So you can set :default_value like:
    
           :default_value: "~/.ssh/<%= config[:keypair_name] %>-id_rsa"
      This may assume that keypair_name is setup before abd would need:
      - :after: <datas>
    
  • Returns:

    • value : value entered by the end user.

  • Raises :



153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/core/core_setup_ask.rb', line 153

def _setup_ask_data_from_list(data, list_options, desc, options)
  obj_to_load = list_options[:object]

  result = _setup_choose_list_process(obj_to_load, list_options,
                                      options[:default_value])

  list = result[:list]
  default = options[:default_value]
  default = result[:default_value] unless result[:default_value].nil?

  begin
    Lorj.debug(3, "'%s': ERB on default value '%s'", data, default)
    default = erb(default) unless default.nil?
  rescue => e
    PrcLib.warning("ERB error with :%s/:default_value '%s'.\n%s",
                   data, result[:default_value], e.message)
  else
    default = nil if default == ''
    Lorj.debug(3, "'%s': default value '%s'", data, default)
    options[:default_value] = default
  end

  is_strict_list = (list_options[:validate] == :list_strict)

  if list.nil?
    list = []

    if is_strict_list
      PrcLib.fatal(1, "%s requires a value from the '%s' query which is "\
                  'empty.', data, obj_to_load)
    else
      list << 'Not in this list'
    end
  end

  value = _setup_choose_data_from_list(data, desc, list, options)

  if !is_strict_list && value == 'Not in this list'
    value = _setup_ask_data_from_keyboard(desc, data, options)
  end
  value
end

#_setup_ask_post_process(proc) ⇒ Object

Execute the post process on data entered by the user

  • returns

    • false if the process ask the user to re-enter a value.

    • true otherwise.



75
76
77
78
79
80
81
82
83
84
85
86
# File 'lib/core/core_setup_ask.rb', line 75

def _setup_ask_post_process(proc)
  return true if proc.nil?

  result = @process.method(proc).call

  unless result.boolean?
    PrcLib.debug("Warning: '%s' did not return any boolean"\
                 ' value. Ignored', proc)
    result = true
  end
  result
end

#_setup_attrs_depends_on(dependencies, attr_name, attrs) ⇒ Object

Internal setup function - Identify a list of attributes from depends_on

If the attribute has a object dependency, attributes attached are added. If the object has depends_on



933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
# File 'lib/core/core_setup_init.rb', line 933

def _setup_attrs_depends_on(dependencies, attr_name, attrs)
  return [] unless attrs.is_a?(Array) && attrs.length > 0

  result = []

  Lorj.debug(3, "%s: depends on added '%s'", attr_name, attrs.join(', '))

  attrs.each do |a|
    data = Lorj.data.auto_section_data(a)

    if data.rh_exist?(:list_values, :object)
      element = _setup_bs_objs_deps(dependencies,
                                    data.rh_get(:list_values, :object))
      element[:attrs] += dependencies.rh_get(:object, element[:obj], :attrs)
    else
      element = { :attrs => [] }
    end

    if data[:depends_on].is_a?(Array)
      element[:depends_on] = _setup_attrs_depends_on(dependencies, a,
                                                     data[:depends_on])
    else
      element[:depends_on] = []
    end

    attrs_list = element[:attrs] + element[:depends_on]
    attrs_list.uniq!
    result += attrs_list
  end
  result.uniq
end

#_setup_bs_levels(attrs, level) ⇒ Object

Uses attributes level detected to initialize the list of steps/orders.



652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
# File 'lib/core/core_setup_init.rb', line 652

def _setup_bs_levels(attrs, level)
  steps = [[]]
  pos = 0

  loop do
    attrs.clone.each do |k, v|
      cur_level = v.rh_get(:group, :level)
      next unless cur_level == level

      attrs_to_add = v[:attrs] + v.rh_get(:group, :attrs).uniq
      attrs.reject! do |attr, _|
        res = attrs_to_add.include?(attr)
        steps[pos] << { attr => attrs[attr] } if res
        res
      end

      steps[pos + 1] = [] if steps[pos + 1].nil?

      steps[pos + 1] << { k => attrs[k] }
      attrs.reject! { |attr, _| attr == k }
    end
    level += 1
    break if level == 0
    pos += 1
  end
  steps
end

#_setup_bs_list_query(dependencies, attr_name, data, element) ⇒ Object



775
776
777
778
779
780
781
782
783
784
785
786
787
788
# File 'lib/core/core_setup_init.rb', line 775

def _setup_bs_list_query(dependencies, attr_name, data, element)
  return unless data.rh_exist?(:list_values, :object)

  element[:obj] = data.rh_get(:list_values, :object)
  element[:group] = _setup_bs_objs_deps(dependencies, element[:obj])

  _object_params_event(element[:obj], :query_e, :data).each do |attr_obj|
    element[:attrs] << attr_obj.key_tree
  end
  Lorj.debug(5, "attr setup '%s': query '%s' (+ %s) and "\
                "requires '%s' (+ %s)", attr_name,
             element[:obj], element[:group][:objs],
             element[:attrs], element[:group][:attrs] - element[:attrs])
end

#_setup_bs_objs(attrs_done, dependencies, attr_name) ⇒ Object

Internal setup function to build the list of attribute deps



682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
# File 'lib/core/core_setup_init.rb', line 682

def _setup_bs_objs(attrs_done, dependencies, attr_name)
  # Check if this attr requires an object query.
  Lorj.debug(2, "-- Checking '%s' attribute --", attr_name)
  data = Lorj.data.auto_section_data(attr_name)

  element = _setup_bs_objs_init(data)

  return element if data.nil?

  return element unless data.rh_exist?(:list_values, :object) ||
                        data[:depends_on].is_a?(Array)

  _setup_bs_list_query(dependencies, attr_name, data, element)

  # ensure attribute dependency is dynamically added to the list of
  # object deps.
  _setup_bs_objs_new_dep(dependencies, attr_name, element)

  element[:depends_on] = []
  element[:depends_on] = data[:depends_on] if data[:depends_on].is_a?(Array)

  group = element[:group]
  if group[:objs].length > 0
    _setup_set_group_level(dependencies, attrs_done, attr_name,
                           group, group[:objs].sort)
  else
    _setup_set_group_level(dependencies, attrs_done, attr_name,
                           group, [element[:obj]])
  end

  _setup_attrs_depends_on(dependencies, attr_name,
                          element[:depends_on])

  element
end

#_setup_bs_objs_deps(dependencies, object_type) ⇒ Object

Internal setup function - Extract object data information.



898
899
900
901
902
903
904
905
906
907
908
909
# File 'lib/core/core_setup_init.rb', line 898

def _setup_bs_objs_deps(dependencies, object_type)
  group = { :objs => nil, :attrs => nil }
  if dependencies.rh_exist?(:objects, object_type)
    group[:objs], group[:attrs] = _setup_objects_attr_needs(dependencies,
                                                            object_type)
    return group
  end
  _setup_identify_dep_init(dependencies, object_type)
  group[:objs], _, group[:attrs] = _setup_identify_deps(dependencies,
                                                        object_type)
  group
end

#_setup_bs_objs_init(data) ⇒ Object

Initialize attribute element.



719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
# File 'lib/core/core_setup_init.rb', line 719

def _setup_bs_objs_init(data)
  element = { :obj => nil, :setup => false, :ask_sort => nil,
              :group => { :objs => [], :attrs => [] },
              :attrs => [], :ask_step => nil }

  return element if data.nil?

  element[:setup] = data[:account] if data.rh_get(:account).boolean?
  if data.rh_get(:ask_sort).is_a?(Fixnum)
    element[:ask_sort] = data[:ask_sort]
  end

  element[:ask_step] = data[:ask_step]

  element
end

#_setup_bs_objs_new_dep(dependencies, parent_attr_name, element) ⇒ Object

Internal function to verify if any attributes adds an object dependency



738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
# File 'lib/core/core_setup_init.rb', line 738

def _setup_bs_objs_new_dep(dependencies, parent_attr_name, element)
  attrs = (element[:attrs] + element[:group][:attrs]).uniq
  return if attrs.length == 0

  found = false

  attrs.each do |attr_name|
    obj_found = dependencies.rh_get(:attributes, attr_name, :obj)
    next if obj_found.nil?

    objs = element.rh_get(:group, :objs)
    next if objs.include?(obj_found)

    dep = dependencies.rh_get(:attributes, attr_name)
    # Updating list of deps objs
    objs << obj_found
    objs = (objs + dep[:group][:objs]).uniq
    element.rh_set(objs, :group, :objs)

    # Undating list of deps attributes
    attrs = element.rh_get(:group, :attrs)
    attrs_found = (attrs + dep[:attrs] + dep[:group][:attrs]).uniq
    element.rh_set(attrs_found, :group, :attrs)

    Lorj.debug(4, "attr setup '%s': '%s' dependent attribute adds a new"\
                  " object dependency '%s'",
               parent_attr_name, attr_name, obj_found)
    found = true
  end
  return unless found

  Lorj.debug(5, "attr setup '%s': query '%s' (+ %s) and "\
                "requires '%s' (+ %s)", parent_attr_name,
             element[:obj], element[:group][:objs],
             element[:attrs], element[:group][:attrs] - element[:attrs])
end

#_setup_build_process_params(option_params, params) ⇒ Object



96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/core/core_setup_list.rb', line 96

def _setup_build_process_params(option_params, params)
  return if option_params.nil?

  option_params.each do |key, value|
    next if value.nil?
    begin
      value = erb(value)
    rescue => e
      Prclib.warning("ERB:process parameter failed to set '%s' with '%s'."\
                     "\n%s", key, value, e.message)
    end
    params << { key => value }
  end
end

#_setup_build_steps_from(dependencies) ⇒ Object

Internal setup function to complete the list of attributes and organize attributes by step as requested by attr dependencies It loops on a list of unanalyzed attributes to determine new objects/attributes

The analyze is based on attributes having setup obj (and group of deps) required

A new level is added:

  • when a new group of deps is found. Then each attributes required decrease the level by 1.

  • when a group already exist, nothing is done

In case of depends_on, the attribute level is set to 0 and depends_on attributes level are decreased. each attributes parsed get a level 0 if requires a group is requires otherwise level is set to nil.



618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
# File 'lib/core/core_setup_init.rb', line 618

def _setup_build_steps_from(dependencies)
  count = dependencies[:attributes].length
  attrs_done = {}
  level = 0
  loop do
    attrs = dependencies[:attributes].clone
    attrs.each_key do |attr_name|
      next if attrs_done.key?(attr_name)

      element = _setup_bs_objs(attrs_done, dependencies, attr_name)

      attrs_done[attr_name] = element
      dependencies.rh_set(element, :attributes, attr_name)

      if element.rh_exist?(:group, :level)
        level = [level, element[:group][:level]].min
      end

      list_attrs = (element[:attrs] + element.rh_get(:group, :attrs)).uniq

      next if list_attrs.length == 0
      Lorj.debug(2, "setup: '%s' attribute dependency found '%s'",
                 attr_name, list_attrs.join(', '))
    end
    break if dependencies[:attributes].length == count
    count = dependencies[:attributes].length
  end

  # Thanks to attributes/group deps, set levels
  attrs = dependencies[:attributes]
  _setup_bs_levels(attrs, level)
end

#_setup_check_additional(setup_steps) ⇒ Object

check for any additional data to ask to the user thanks to the /:setup/:ask_step/<steps>/:add option of each steps

  • Args :

    • setup_steps : Hash. setup data structure to update.

      It will update setup_steps:/:order 2 dimensions array
      
  • Returns:

  • Raises :



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
# File 'lib/core/core_setup_init.rb', line 112

def _setup_check_additional(setup_steps)
  setup_steps.each do |step|
    step_name = step[:name]
    value = _setup_step_definition
    next unless value.is_a?(Hash) && value.rh_exist?(step_name, :add)

    datas_to_add = value.rh_get(step_name, :add)
    datas_to_add.each do |data_to_add|
      order_array = step[:order]
      next if _setup_attr_already_added?(order_array, data_to_add)

      _setup_data_insert(step, data_to_add)
    end
  end
end

#_setup_choose_data_from_list(data, desc, list, options) ⇒ Object

Internal setup function to present the list to the user and ask to choose.

  • Args :

  • data : Data to ask.

  • desc : Data description

  • list : list of values to choose

  • options : Used when user have to enter a string instead of

    selecting from a list.
    
  • Returns:

    • value : value entered by the end user.

  • Raises :



212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/core/core_setup_ask.rb', line 212

def _setup_choose_data_from_list(data, desc, list, options)
  default = @config.get(data, options[:default_value])
  Lorj.debug(3, "'%s': Getting value from config - '%s'(from '%s' - "\
                "sections '%s')"\
                " (default is '%s')",
             data, default, @config.where?(data), Lorj.data.sections(data),
             options[:default_value])

  say_msg = format("Select '%s' from the list:", desc)
  say_msg += format(' |%s|', default) unless default.nil?
  say(say_msg)
  value = choose do |q|
    q.choices(*list)
    q.default = default if default
  end
  value
end

#_setup_choose_list_process(obj_to_load, list_options, default_value = nil) ⇒ Object

Internal setup function to ask to the end user from a list.

  • Args :

  • obj_to_load : Object to get list from.

  • list_options: list and validation options

  • Returns:

    • Hash : list of possible values and default. :default_value : Value pre-selected. :list : list of possible values

  • Raises :



101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/core/core_setup_ask.rb', line 101

def _setup_choose_list_process(obj_to_load, list_options,
                               default_value = nil)
  result = { :list => [], :default_value => nil }
  case list_options[:query_type]
  when :controller_call
    result = _setup_list_from_controller_call(obj_to_load, list_options,
                                              default_value)
  when :query_call
    result = _setup_list_from_query_call(obj_to_load, list_options,
                                         default_value)
  when :process_call
    result = _setup_list_from_process_call(obj_to_load, list_options,
                                           default_value)
  else
    PrcLib.runtime_fail "%s: '%s' invalid query type. valid is: '%s'.",
                        obj_to_load, list_options[:values_type],
                        [:controller_call, :query_call, :process_call]
  end
  result
end

#_setup_display_data(data, options) ⇒ Object

internal setup function to display step information

  • Args :

  • data : data name to ask.

  • options : data options

  • Returns:

  • desc : Description of the data to ask.

  • Raises :



1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
# File 'lib/core/core_setup_init.rb', line 1039

def _setup_display_data(data, options)
  desc = format("'%s' value", data)

  unless options[:explanation].nil?
    begin
      puts format('%s: %s',
                  data,
                  erb(options[:explanation]))
    rescue => e
      PrcLib.error "setup key '%s/:explanation' : %s", data, e.message
    end
  end

  begin
    desc = erb(options[:desc]) unless options[:desc].nil?
  rescue => e
    PrcLib.error "setup key '%s/:desc' : %s", data, e.message
  end

  desc
end

#_setup_display_step(setup_step, step) ⇒ Object

case attr_type

when :data
  return unless _setup_obj_param_is_data(setup_steps,
                                         inspected_objects, attr_name)
  inspected_objects << attr_name
  return
when :CloudObject
  return if objs_to_inspect.include?(attr_name) ||
            inspected_objects.include?(attr_name)
  # New object to inspect
  objs_to_inspect << attr_name
end

end



1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
# File 'lib/core/core_setup_init.rb', line 1015

def _setup_display_step(setup_step, step)
  Lorj.debug(2, 'Ask step %s:', step)
  puts ANSI.bold(setup_step[:desc]) unless setup_step[:desc].nil?
  begin
    erb_msg = ANSI.yellow(
      erb(setup_step[:explanation])
    ) unless setup_step[:explanation].nil?
  rescue => e
    PrcLib.error "setup step '%d/:explanation' : %s", step, e.message
  end
  puts format("%s\n\n", erb_msg) unless erb_msg.nil?
end

#_setup_id_each(dependencies, model_object, new_path, attr_path, attr_params) ⇒ Object



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
# File 'lib/core/core_setup_init.rb', line 233

def _setup_id_each(dependencies, model_object, new_path,
                   attr_path, attr_params)
  objects = []
  attrs = []
  deps_attrs = []
  deps_objects = []

  attr_name = KeyPath.new(attr_path).key_tree
  attr_type = attr_params[:type]

  case attr_type
  when :data
    attr_to_add = _setup_id_init_data_deps(dependencies, attr_name)
    if attr_to_add
      model_object[:attrs] << attr_to_add
      attrs << attr_to_add
    end
  when :CloudObject
    if _setup_identify_dep_init(dependencies, attr_name, new_path)
      found_obj,
        found_attrs,
        found_deps_attrs = _setup_identify_deps(dependencies,
                                                attr_name, new_path)
    else
      found_obj = dependencies.rh_get(:objects, attr_name, :objects)
      found_attrs = dependencies.rh_get(:objects, attr_name, :attrs)
      found_deps_attrs = []
    end
    deps_objects = (deps_objects + found_obj).uniq
    deps_attrs = (deps_attrs + found_attrs + found_deps_attrs).uniq
    model_object[:objects] << attr_name
    objects << attr_name
  end
  [attrs, deps_attrs, objects, deps_objects]
end

#_setup_id_init_data_deps(dependencies, attr_name) ⇒ Object



269
270
271
272
273
274
# File 'lib/core/core_setup_init.rb', line 269

def _setup_id_init_data_deps(dependencies, attr_name)
  return if dependencies[:attributes].key?(attr_name)

  dependencies.rh_set({}, :attributes, attr_name)
  attr_name
end

#_setup_identify(sObjectType, setup_steps) ⇒ Object

Function to build a step/order structure of Attributes. step/order is an array of array. the first array represents the steps the second array represents the list of attributes in a specific order.

This structure is used by setup to ask the list of attributes in a specific order.

It loops on object dependencies, then data definition to determine the list of attributes and their required order.

A new step is created when an attribute, during setup time requires to query an object, which may requires some additional attributes, considered as dependent attributes. The previous step must contains at least the dependent attributes.

Process data definition can influence those detected steps, by assigning an :ask_step to the attribute. Then the default attribute step may be splitted to more steps.

You cannot set an attribute step lower then the detected step. Process data definition can influence the attributes order, by assigning an :ask_order to the attribute.

:setup section of the process data definition (data.yaml) can set the step description or add some extra attributes (not detected by default)

  • Args :

    • sObjectType : Symbol/String. Object type to analyze for list of attributes to setup

    • setup_steps : Hash. setup data structure to update.

      It will update setup_steps:/:order 2 dimensions array
      
  • Returns:

    • setup_steps: Hash updated

  • Raises :



166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'lib/core/core_setup_init.rb', line 166

def _setup_identify(sObjectType, setup_steps)
  # There is 3 sources of data used by setup to build the list of data to
  # setup:
  # - Lorj.data (Lorj::MetaConfig): Process data definition.
  # - config (Lorj::Account)      : Configuration files/runtime data.
  # - PrcLib.model.meta_obj(Hash) : Object definition / mapping

  dependencies = { :objects => {}, :attributes => {} }
  _setup_identify_dep_init(dependencies, sObjectType)

  # Build list of attributes which will be needed for an object and
  # its dependencies

  Lorj.debug(2, '- Checking objects dependencies -')
  _setup_identify_deps(dependencies, sObjectType)

  # Build list of additional attributes and build
  # attribute dependencies thanks to attribute queries.
  Lorj.debug(2, '- Checking attributes dependencies -')
  orders = _setup_build_steps_from(dependencies)

  # Reorganize each required steps thanks to :ask_order
  Lorj.debug(2, '- Re-organizing attributes steps/order -')
  attrs = _setup_reorganize_steps_order(dependencies[:attributes], orders)

  # Apply additionnal steps as described by Lorj.data
  Lorj.debug(2, '- Add extra steps -')
  _setup_reorganize_steps(attrs, orders, setup_steps)
end

#_setup_identify_dep_init(dependencies, object_type, path = []) ⇒ Object

Internal setup function initializing a model object



977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
# File 'lib/core/core_setup_init.rb', line 977

def _setup_identify_dep_init(dependencies, object_type, path = [])
  if path.include?(object_type)
    PrcLib.warning('Loop detection: Be careful! a loop is detected with'\
                   " the dependency from '%s' to '%s'. "\
                   'Dependency ignored.', path.join('/'), object_type)
    return false
  end

  return false if dependencies.rh_exist?(:objects, object_type)

  model_object = { :objects => [], :objects_attrs => [], :attrs => [] }

  dependencies.rh_set(model_object, :objects, object_type)
  true
end

#_setup_identify_deps(dependencies, object_type, path = []) ⇒ Object

Internal setup function to parse objects/attributes dependency list and build objects list and required attributes list.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/core/core_setup_init.rb', line 198

def _setup_identify_deps(dependencies, object_type, path = [])
  model_object = dependencies.rh_get(:objects, object_type)
  objects_list = PrcLib.model.meta_obj.rh_get(object_type, :params, :keys)
  if objects_list.nil?
    PrcLib.warning("'%s' as object type is not valid. Not declared.")
    return [[], [], []]
  end

  objects = []
  attrs = []
  deps_attrs = []
  deps_objects = []
  new_path = path + [object_type]

  objects_list.each do |attr_path, attr_params|
    a, d_a, o, d_o = _setup_id_each(dependencies, model_object, new_path,
                                    attr_path, attr_params)
    attrs += a
    deps_attrs += d_a
    objects += o
    deps_objects += d_o
  end
  attrs.uniq!
  deps_attrs.uniq!
  objects.uniq!
  deps_objects.uniq!

  _sid_show_debug(3, format("'%s' has ", object_type) + '%s',
                  attrs, objects)
  _sid_show_debug(4, format("'%s' has ", object_type) + 'also indirect %s',
                  deps_attrs, deps_objects)

  [(objects + deps_objects).uniq, attrs, deps_attrs]
end

#_setup_list_from_controller_call(obj_to_load, list_options, default) ⇒ Object

Internal setup function to build the list from a controller call.

  • Args :

  • obj_to_load : Object to get list from.

  • list_options: list and validation options

  • Returns:

    • Hash : list of possible values and default. :default_value : Value pre-selected. :list : list of possible values

  • Raises :



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/core/core_setup_list.rb', line 42

def _setup_list_from_controller_call(obj_to_load, list_options, default)
  PrcLib.message("Loading :object #{obj_to_load}.")
  Lorj.debug(3, ':query_type = :controller_call')

  object = @object_data[obj_to_load, :ObjectData]
  object = process_create(obj_to_load) if object.nil?
  return nil if object.nil?

  params = ObjectData.new
  params.add(object)
  params << list_options[:query_params]

  PrcLib.runtime_fail '%s: query_type => :controller_call '\
               'requires missing :query_call declaration'\
               ' (Controller function)',
                      data if list_options[:query_call].nil?

  proc = list_options[:query_call]
  begin
    list = @controller.method(proc).call(obj_to_load, params)
  rescue => e
    PrcLib.runtime_fail "Error during call of '%s':\n%s", proc, e.message
  end
  { :list => list, :default_value => default }
end

#_setup_list_from_process_call(obj_to_load, list_options, default) ⇒ Object

Internal setup function to build the list from a process call.

  • Args :

  • obj_to_load : Object to get list from.

  • list_options: list and validation options

  • Returns:

    • Hash : list of possible values and default. :default_value : Value pre-selected. :list : list of possible values

  • Raises :



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/core/core_setup_list.rb', line 124

def _setup_list_from_process_call(obj_to_load, list_options, default)
  PrcLib.runtime_fail '%s: query_type => :process_call'\
               ' requires missing :query_call declaration'\
               ' (Provider function)',
                      data if list_options[:query_call].nil?
  proc = list_options[:query_call]
  obj_to_load = list_options[:object]
  PrcLib.message("Running process '#{proc}' on :object '#{obj_to_load}'.")
  Lorj.debug(3, ':query_type = :process_call')

  # Building Process function attr_params parameter
  params = ObjectData.new

  params << { :default_value => default }

  _setup_build_process_params(list_options[:query_params], params)

  begin
    proc_method = @process.method(proc)
    result = proc_method.call(obj_to_load, params)
  rescue => e
    PrcLib.runtime_fail "Error during call of '%s':\n%s",
                        proc, e.message
  end

  if result.is_a?(Hash)
    if result[:list].nil? ||
       !result[:list].is_a?(Array)
      PrcLib.debug("Process function '%s' did not return an"\
                   ' :list => Array of list_options.',
                   list_options[:query_call])
    end
  else
    PrcLib.debug("Process function '%s' did not return an"\
                 ' Hash with :list and :default_value')
    result = { :list => [], :default_value => nil }
  end
  result
end

#_setup_list_from_query_call(obj_to_load, list_options, default) ⇒ Object

Internal setup function to build the list from a query call.

  • Args :

  • obj_to_load : Object to get list from.

  • list_options: list and validation options

  • Returns:

    • Hash : list of possible values and default. :default_value : Value pre-selected. :list : list of possible values

  • Raises :



81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/core/core_setup_list.rb', line 81

def _setup_list_from_query_call(obj_to_load, list_options, default)
  PrcLib.message("Querying :object #{obj_to_load}.")
  Lorj.debug(3, ':query_type = :query_call - ')

  query_hash = list_options[:query_params]
  query_hash = {} if query_hash.nil?

  object_list = process_query(obj_to_load, query_hash)

  list = []
  object_list.each { |oElem| list << oElem[list_options[:value]] }

  { :list => list.sort!, :default_value => default }
end

#_setup_loadObject

Load /:setup/:ask_step section of the data.yaml

See lib/core/core_model.rb

  • Returns:

    • hash : setup data structure.

  • Raises :



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/core/core_setup_init.rb', line 39

def _setup_load
  setup_steps = {}

  steps = Lorj.data.setup_data(:steps)
  return setup_steps if steps.nil?

  steps.each do |name, value|
    setup_steps[name] = _setup_load_init(value)
  end

  ask_steps = Lorj.data.setup_data(:ask_step)
  return setup_steps if ask_steps.nil?

  ask_steps.each do |value|
    name = value[:name]
    name = ask_steps.index(value).to_s if name.nil?
    if setup_steps.key?(name)
      setup_steps[name].rh_merge(_setup_load_init(value))
      next
    end
    setup_steps[name] = _setup_load_init(value)
  end

  setup_steps
end

#_setup_load_init(value) ⇒ Object



65
66
67
68
69
70
71
72
73
74
75
# File 'lib/core/core_setup_init.rb', line 65

def _setup_load_init(value)
  value = {} if value.nil?

  {
    :desc => value[:desc],
    :explanation => value[:explanation],
    :pre_step_handler => value[:pre_step_function],
    :order => [[]], # attributes in array of level/order
    :post_step_handler => value[:post_step_function]
  }
end

#_setup_objects_attr_needs(dependencies, object_type) ⇒ Object

Internal setup function - Build list of ALL attributes required for an object

It navigates on loaded dependencies to build the list of attributes.



915
916
917
918
919
920
921
922
923
924
925
926
927
# File 'lib/core/core_setup_init.rb', line 915

def _setup_objects_attr_needs(dependencies, object_type)
  attrs = []

  objects = dependencies.rh_get(:objects, object_type, :objects)
  deps_objects = []
  objects.each do |o|
    attrs += dependencies.rh_get(:objects, o, :attrs)
    found_obj, deps_attrs = _setup_objects_attr_needs(dependencies, o)
    attrs += deps_attrs
    deps_objects += found_obj
  end
  [(objects + deps_objects).uniq, attrs.uniq]
end

#_setup_reorganize_so_befaft(attr_group) ⇒ Object

Internal setup function to re-organize thanks to :before and :after.



346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'lib/core/core_setup_init.rb', line 346

def _setup_reorganize_so_befaft(attr_group)
  attrs = attr_group.map { |a| a.keys[0] }

  attrs.clone.each do |attr_name|
    meta = (attr_name)
    next if meta.nil?
    next unless meta.rh_exist?(:after) || meta.rh_exist?(:before)

    if _setup_reorganize_so_befaft_move?(:after, meta, attrs, attr_name)
      _setup_reorganize_so_befaft_move(:after, meta, attrs, attr_group,
                                       attr_name)
    end

    next unless _setup_reorganize_so_befaft_move?(:before, meta, attrs,
                                                  attr_name)

    _setup_reorganize_so_befaft_move(:before, meta, attrs, attr_group,
                                     attr_name)
  end
  attr_group
end

#_setup_reorganize_so_befaft_move(where, meta, attrs, attr_group, attr_name) ⇒ Object

Do the move



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# File 'lib/core/core_setup_init.rb', line 379

def _setup_reorganize_so_befaft_move(where, meta, attrs, attr_group,
                                     attr_name)
  old = attrs.index(attr_name)
  ref = meta[where]
  new = attrs.index(ref)

  # Must be inserted after the attribute => + 1
  new += 1 if where == :after

  Lorj.debug(5, ":%s: Move '%s' %s '%s'"\
                    " - pos '%s' => pos '%s'",
             where, attr_name, where, ref, old, new)

  attrs.insert(new, attrs.delete(attr_name))
  attr_group.insert(new, attr_group.delete(attr_group[old]))
end

#_setup_reorganize_so_befaft_move?(where, meta, attrs, attr_name) ⇒ Boolean

return true if there is a need to move the element before/after



369
370
371
372
373
374
375
376
# File 'lib/core/core_setup_init.rb', line 369

def _setup_reorganize_so_befaft_move?(where, meta, attrs, attr_name)
  element = meta[where]
  element = nil unless (attrs - [attr_name]).include?(element)

  cur = attrs.index(attr_name)
  return (element && cur < attrs.index(element)) if where == :after
  (element && cur > attrs.index(element))
end

#_setup_reorganize_so_sort(attr_group) ⇒ Object

Internal setup function to re-organize thanks to :ask_sort



397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
# File 'lib/core/core_setup_init.rb', line 397

def _setup_reorganize_so_sort(attr_group)
  attr_subgroups = []
  attr_noorder = []

  attr_group.each do |attr|
    attr_def = attr[attr.keys[0]]
    if attr_def[:ask_sort].is_a?(Fixnum)
      Lorj.debug(4, "'%s' position requested is '%s'",
                 attr.key(attr_def), attr_def[:ask_sort])
      if attr_subgroups[attr_def[:ask_sort]].nil?
        attr_subgroups[attr_def[:ask_sort]] = [attr]
      else
        attr_subgroups[attr_def[:ask_sort]] << attr
      end
    else
      attr_noorder << attr
    end
  end

  attr_subgroups.flatten!

  attr_subgroups + attr_noorder
end

#_setup_reorganize_steps(steps_unordered, steps, setup_steps) ⇒ Object

Internal setup function to re-organize steps as described by :setup/:steps section and data property :step



424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/core/core_setup_init.rb', line 424

def _setup_reorganize_steps(steps_unordered, steps, setup_steps)
  steps << steps_unordered

  # build the steps attributes
  build_steps = [{ :order => {} }]
  build_step = 0
  step_name = nil
  #  cur_step = build_steps[build_step]
  Lorj.debug(3, "Building setup step position '%s'", build_step)

  steps.each_index do |step_index|
    steps[step_index].each do |attr|
      attr_name = attr.keys[0]
      attr_def = attr[attr_name]

      unless attr_def[:setup]
        Lorj.debug(2, "'%s' is ignored. configured with :account = '%s'",
                   attr_name, attr_def[:setup])
        next
      end

      step_name = _setup_ros_get_step_name(attr_def)

      next if _setup_ros_same_step_name(build_steps[build_step],
                                        step_index, step_name, attr_name)

      build_step = _setup_ros_set_step(:build_steps => build_steps,
                                       :build_step => build_step,
                                       :setup_steps => setup_steps,
                                       :step_index => step_index,
                                       :step_name => step_name,
                                       :attr_name => attr_name)

      _setup_ros_add_attribute(build_steps[build_step][:order],
                               step_index, attr_name)
    end
  end

  if build_steps.last[:name].nil?
    _setup_ros_set_step(:build_steps => build_steps,
                        :setup_steps => setup_steps,
                        :step_index => steps.length - 1,
                        :attr_name => :default)
  end

  build_steps
end

#_setup_reorganize_steps_order(attrs, attr_groups) ⇒ Object

Internal setup function to Reorganize attributes order thanks following data definition:

  • :sections/<Section>/<Attribute>/:ask_sort: (FixNum) Defines the list of attributes that needs to be setup before.

This function will first of all determine the order thanks to :ask_sort in the current step group.



317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
# File 'lib/core/core_setup_init.rb', line 317

def _setup_reorganize_steps_order(attrs, attr_groups)
  attr_groups.collect do |attr_group|
    index = attr_groups.index(attr_group)
    Lorj.debug(3, "Step '%s' analyzing re-organisation", index)
    res = _setup_reorganize_so_sort(attr_group)
    res = _setup_reorganize_so_befaft(res)

    old = attr_group.map { |attr| attr.keys[0] }
    new = res.map { |attr| attr.keys[0] }
    Lorj.debug(3, "Step '%s' reorganized from '%s' to '%s'",
               index, old, new) unless old == new
    attr_groups[index] = res
  end

  attrs_list = []
  attrs.each do |k, v|
    attrs_list << { k => v }
  end
  res = _setup_reorganize_so_sort(attrs_list)
  res = _setup_reorganize_so_befaft(res)

  old = attrs_list.map { |attr| attr.keys[0] }
  new = res.map { |attr| attr.keys[0] }
  Lorj.debug(3, "unordered reorganized from '%s' to '%s'",
             old, new) unless old == new
  res
end

#_setup_ros_add_attribute(step_order, stepo_index, attr_name) ⇒ Object

Internal function to add an attribute to the step_order structure.



490
491
492
493
# File 'lib/core/core_setup_init.rb', line 490

def _setup_ros_add_attribute(step_order, stepo_index, attr_name)
  step_order[stepo_index] = [] if step_order[stepo_index].nil?
  step_order[stepo_index] << attr_name
end

#_setup_ros_find_buildstep(build_steps, step_order_index, searched_step_name) ⇒ Object

Internal Function searching in build_steps a step_name. If found, the index is kept.

If found, it compares the index with the current step_index It will be considered valid if the step index has a step_index in :orders or if the step_index - 1 is the found in the last known step.

If the step is not found, the index returned will be a new index to create in build_steps.

  • args:

    • build_steps : List of build_steps already identified.

    • step_order_index : current step order index to add an attribute to.

    • step_name : Step name to search.

  • return:

    • index : It returns a correct build_step to use.

    • nil : nil if there is no valid index to return.



568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/core/core_setup_init.rb', line 568

def _setup_ros_find_buildstep(build_steps, step_order_index,
                                searched_step_name)
  return 0 if step_order_index == 0

  step_found = nil
  last_step_order_found = nil

  build_steps.each_index do |i|
    step_found = i if build_steps[i][:name] == searched_step_name
    if build_steps[i][:order].include?(step_order_index - 1)
      last_step_order_found = i
    end
  end

  return build_steps.length if step_found.nil?

  if step_found
    if build_steps[step_found][:order].include?(step_order_index)
      return step_found
    end

    return step_found if step_found >= last_step_order_found
  end

  PrcLib.warning("Unable to set step '%s' at position %s. "\
                 "This step is already at position '%s'. "\
                 "Due to attribute dependencies, attribute '%' cannot be"\
                 ' asked at that step. Please correct the process'\
                 ' definition. ',
                 step_name, build_steps.index(e),
                 build_steps.length - 1, attr_name)
  nil
end

#_setup_ros_get_step_name(attr_def) ⇒ Object

Internal function to get the step name to use



473
474
475
476
477
478
479
# File 'lib/core/core_setup_init.rb', line 473

def _setup_ros_get_step_name(attr_def)
  return nil if attr_def[:ask_step].nil?

  step_name = attr_def[:ask_step]
  step_name = step_name.to_s if step_name.is_a?(Fixnum)
  step_name
end

#_setup_ros_same_step_name(build_step, stepo_index, step_name, attr_name) ⇒ Object

Internal function checking if the step is already assigned



482
483
484
485
486
487
# File 'lib/core/core_setup_init.rb', line 482

def _setup_ros_same_step_name(build_step, stepo_index, step_name, attr_name)
  return false unless step_name.nil? || build_step[:name] == step_name

  _setup_ros_add_attribute(build_step[:order], stepo_index, attr_name)
  true
end

#_setup_ros_set_step(params) ⇒ Object

Set the step data to the current order built.

If the step has already been set, a warning is printed.

  • returns:

    • +Return the



504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
# File 'lib/core/core_setup_init.rb', line 504

def _setup_ros_set_step(params)
  build_steps = params[:build_steps]
  build_step = params[:build_step]
  step_index = params[:step_index]
  step_name = params[:step_name]
  attr_name = 'of latest step'
  attr_name = params[:attr_name] unless params[:attr_name].nil?

  setup_step = params[:setup_steps][step_name]
  if setup_step.nil?
    PrcLib.warning("Attribute '%s': Setup step '%s' is not defined.",
                   attr_name, step_name)
    return build_step
  end

  step_found = _setup_ros_find_buildstep(build_steps, step_index,
                                         step_name)

  return build_step if step_found.nil?

  if step_found == build_steps.length
    step = { :order => { step_index => [] } }
    Lorj.debug(3, "Building setup step position '%s'", step_found)
    build_steps << step
  end

  build_step = step_found
  step = build_steps[build_step]

  return build_step if step[:name] == step_name

  step[:name] = step_name

  step[:desc] = setup_step[:desc]
  step[:explanation] = setup_step[:explanation]
  step[:pre_step_handler] = setup_step[:pre_step_function]
  step[:post_step_handler] = setup_step[:post_step_function]

  Lorj.debug(3, "Requested by '%s' attribute, setup step position '%s'"\
                " is assigned to '%s'", attr_name,
             build_steps.length - 1, step_name)
  build_step
end

#_setup_set_group_case1(attrs_done, attr_name, group, objs) ⇒ Object

Case 1 - equivalent group?



837
838
839
840
841
842
843
844
845
846
847
848
# File 'lib/core/core_setup_init.rb', line 837

def _setup_set_group_case1(attrs_done, attr_name, group, objs)
  attrs_done.each do |k, v|
    next unless v.rh_get(:group, :objs) == objs ||
                (v.rh_get(:group, :objs).length == 0 && v[:obj] == objs[0])

    group[:level] = v.rh_get(:group, :level)
    Lorj.debug(5, "attr setup '%s': Equivalent: '%s' group level set to %s",
               attr_name, k, group[:level])
    return false
  end
  true
end

#_setup_set_group_case2(dependencies, attrs_done, attr_name, group, objs) ⇒ Object

case 2 - existing group found as subgroup?



851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
# File 'lib/core/core_setup_init.rb', line 851

def _setup_set_group_case2(dependencies, attrs_done, attr_name, group, objs)
  attr_subgroups = []
  level = nil
  attrs_done.each do |k, v|
    group_to_check = v.rh_get(:group, :objs)
    next if objs - [v[:obj]] == objs && objs - group_to_check == objs

    attr_subgroups << k
    if level.nil?
      level = v.rh_get(:group, :level)
    else
      level = [v.rh_get(:group, :level), level].max
    end
  end

  if level
    group[:level] = level
    Lorj.debug(5, "attr setup '%s': group level set to %s",
               attr_name, group[:level])

    attr_subgroups.each do |v|
      group = dependencies.rh_get(:attributes, v, :group)
      group[:level] += -1
      Lorj.debug(5, "attr setup '%s': attribute subgroup '%s' level"\
                    ' decreased: group level set to %s',
                 attr_name, v, group[:level])
    end
    return false
  end
  true
end

#_setup_set_group_case34(attrs_done, attr_name, group, objs) ⇒ Object

case 3 - Is a subgroup of existing group?



884
885
886
887
888
889
890
891
892
893
894
895
# File 'lib/core/core_setup_init.rb', line 884

def _setup_set_group_case34(attrs_done, attr_name, group, objs)
  group[:level] = -1 # default is case 4 - new group!

  attrs_done.each_value do |v|
    group_to_check = v.rh_get(:group, :objs)
    next if group_to_check - objs == group_to_check

    group[:level] = [group[:level], v.rh_get(:group, :level) - 1].min
  end
  Lorj.debug(5, "attr setup '%s': group level set to '%s'",
             attr_name, group[:level])
end

#_setup_set_group_level(dependencies, attrs_done, attr_name, group, objs) ⇒ Object

Function parsing the attrs_done to found equivalent group or subgroup.

    1. search for equivalent group

    copy the equivalent group level to the group tested. return if updated

    1. search for any subgroup already treated.

    The group will get the highest level each subgroup (part of the new group) will be decreased. return if updated

    1. loop in groups if the tested group is a subgroup of an existing group

    The group tested will get the lowest group level - 1 return if updated

    1. the group level is set with -1



828
829
830
831
832
833
834
# File 'lib/core/core_setup_init.rb', line 828

def _setup_set_group_level(dependencies, attrs_done, attr_name, group, objs)
  return unless _setup_set_group_case1(attrs_done, attr_name, group, objs)
  return unless _setup_set_group_case2(dependencies, attrs_done,
                                       attr_name, group, objs)

  _setup_set_group_case34(attrs_done, attr_name, group, objs)
end

#_setup_step_definitionObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/core/core_setup_init.rb', line 77

def _setup_step_definition
  setup_steps = {}
  steps = Lorj.data.setup_data(:steps)
  return setup_steps if steps.nil?

  steps.each do |name, value|
    setup_steps[name] = value
  end

  ask_steps = Lorj.data.setup_data(:ask_step)
  return setup_steps if ask_steps.nil?

  ask_steps.each do |value|
    name = value[:name]
    name = ask_steps.index(value).to_s if name.nil?
    if setup_steps.key?(name)
      setup_steps[name].rh_merge(value)
      next
    end
    setup_steps[name] = value
  end
  setup_steps
end

#_sid_show_debug(level, str, attrs, objects) ⇒ Object

Internal setup function to display debug info related to _setup_identify_deps



278
279
280
281
282
283
284
285
# File 'lib/core/core_setup_init.rb', line 278

def _sid_show_debug(level, str, attrs, objects)
  data = []
  data << format("'%s' attributes", attrs.join(', ')) if attrs.length > 0

  data << format("'%s' objects", objects.join(', ')) if objects.length > 0

  Lorj.debug(level, str, data.join(' and ')) if data.length > 0
end

#account_data_import(data, name = nil) ⇒ Object

Function to import an account data in Lorj::Account.

The ‘account’ layer is not cleaned before. If you need to clean it up, do:

config.ac_new(, controller_name)

or if the Hash data contains :name and :provider

config.ac_erase

To save it in a file, you will need to call

config.ac_save(filename)

If you pass ‘name’ and ‘controller’, ac_update will be used to update the account data If the imported data contains name and controller data, by default, it will call ac_update.

The location used comes from PrcLib.data_path Passwords will be encrypted by the internal .key file stored in PrcLib.pdata_path

The imported Hash will follow the process data model. But it won’t verify if some data are missed for any object action (create/delete/…)

  • Args :

    • data : Account data to import.

    • name : Optional. Name of the account.

  • Raises : No exceptions



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/core/core_import_export.rb', line 100

def (data, name = nil)
  (data, name)

  entr = _get_encrypt_key

  data.each do |s, sh|
    sh.each do |k, v|
      key = "#{s}##{k}"
      data_def = Lorj.data.auto_section_data(key)
      if data_def && data_def[:encrypted].is_a?(TrueClass)
        v = Lorj::SSLCrypt.encrypt_value(v, entr)
      end
      config.set(key, v, :name => 'account')
    end
  end
end

#account_export(map = nil, with_name = true, account_only = true, processes_options = {}) ⇒ Object

Function to export a Lorj Account in an encrypted Hash.

The encrypted Hash will be encrypted by a new key returned. The content of the hash will built thanks to a Hash mapping or the list of data list in the config ‘account’ layer.

  • Args :

    • map : Hash map of fields to extract. if map is nil, the export function will loop in the list of keys in the ‘account’ layer. if map is provided, following data are expected:

      • <key> : Data key to extract from config.

        • :keys: Array. SubHash tree of keys to create. If :keys is missing, the Data key will define the SubHash tree to use.

          Ex:

          map = {
            # like :keys => [credentials, auth_uri]
            'credentials#auth_uri' => {},
            # extract from maestro but export under :server
            'maestro#image_name' => {:keys => [:server, image_name]}
            }
          
    • with_name : True to extract :name and :provider as well. True by default.

    • account_only : True data extracted must come exclusively from the config ‘account’ layer.

    • processes_options : Hash. Export options for processes

      • :exclude: Array. name of process to exclude.

  • returns :

    • key: String. Key used to encrypt.

    • env_hash: String. Base64 encrypted Hash.

    OR

    • nil if issues.



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'lib/core/core_import_export.rb', line 150

def (map = nil, with_name = true,  = true,
                   processes_options = {})
  map =  if map.nil?

  map.merge!('account#name' => {}, 'account#provider' => {}) if with_name

  entr = _get_encrypt_key
  rhash = {}
  map.each do |k, v|
    data_def = Lorj.data.auto_section_data(k)

    if 
      data = config.get(k, nil, :name => 'account')
    else
      data = config[k]
    end

    rhash_kpath = _export_keys_as_keypath(k, v)
    if !data_def.nil? && data_def[:encrypted].is_a?(TrueClass)
      data = Lorj::SSLCrypt.get_encrypted_value(data, entr, data_def[:desc])
    end
    rhash.rh_set(data, *(rhash_kpath.tree))
  end

  entr = Lorj::SSLCrypt.new_encrypt_key
  export_data = { :enc_data => Lorj::SSLCrypt.encrypt_value(rhash.to_yaml,
                                                            entr) }
  export_data[:processes] = _export_processes(processes_options)
  [entr, export_data.to_yaml]
end

#cache_objects_keysObject

Function to get Lorj core data cache keys.

Args

Return

  • List of objects in cache.



185
186
187
# File 'lib/core/lorj_basedefinition.rb', line 185

def cache_objects_keys
  @object_data[].keys
end

#configObject

Reference to the config object.

See Lorj::Config or Lorj::Account for details



71
72
73
74
# File 'lib/core/lorj_basedefinition.rb', line 71

def config
  PrcLib.runtime_fail 'No config object loaded.' unless @config
  @config
end

#controller_connect(sObjectType, params = nil) ⇒ Object

controller_connect call lorj framework to execute a controller connection task

parameters:

  • object_type: Lorj object type to use for the connection.

  • params : Parameters to use for connection.



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/core/core_controller.rb', line 30

def controller_connect(sObjectType, params = nil)
  _add_instant_config(params)

  controller_params = _get_controller_params(sObjectType,
                                             :create_e, :connect)
  controller_obj = @controller.connect(sObjectType, controller_params)
  data_obj = Lorj::Data.new
  data_obj.base = self
  data_obj.set(controller_obj, sObjectType) do |sObjType, oObject|
    begin
      _return_map(sObjType, oObject)
   rescue => e
     PrcLib.runtime_fail 'connect %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end
  @object_data.add data_obj
  data_obj
end

#controller_create(sObjectType, params = nil) ⇒ Object

controller_create call lorj framework to execute a controller creation task

parameters:

  • object_type: Lorj object type to use for the creation.

  • params : Parameters to use for creation.



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/core/core_controller.rb', line 55

def controller_create(sObjectType, params = nil)
  _add_instant_config(params)

  # The process ask the controller to create the object.
  # controller_params have to be fully readable by the controller.
  controller_params = _get_controller_params(sObjectType,
                                             :create_e, :create)
  controller_obj = @controller.create(sObjectType, controller_params)
  data_obj = Lorj::Data.new
  data_obj.base = self
  data_obj.set(controller_obj, sObjectType) do |sObjType, oObject|
    begin
      _return_map(sObjType, oObject)
   rescue => e
     PrcLib.runtime_fail 'create %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end
  @object_data.add data_obj

  _remove_instant_config(params)

  data_obj
end

#controller_delete(sObjectType, params = nil) ⇒ Object

controller_delete call lorj framework to execute a controller deletion task

parameters:

  • object_type: Lorj object type to use for the deletion.

  • params : Parameters to use for deletion.

returns:

  • The controller must return true to inform about the real deletion



89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/core/core_controller.rb', line 89

def controller_delete(sObjectType, params = nil)
  _add_instant_config(params)

  controller_params = _get_controller_params(sObjectType,
                                             :delete_e, :delete)
  PrcLib.runtime_fail "delete Controller - %s: Object '%s' is not loaded.",
                      @controller.class,
                      key unless controller_params.exist?(sObjectType)
  state = @controller.delete(sObjectType, controller_params)
  @object_data.delete(sObjectType) if state

  _remove_instant_config(params)

  state
end

#controller_get(sObjectType, sUniqId, params = nil) ⇒ Object

controller_get call lorj framework to execute a controller get task

parameters:

  • object_type: Lorj object type to use for the get.

  • params : Parameters to use for get.

returns:

  • Return a Lorj::Data representing the data retrieved by the controller.



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/core/core_controller.rb', line 113

def controller_get(sObjectType, sUniqId, params = nil)
  _add_instant_config(params)

  controller_params = _get_controller_params(sObjectType,
                                             :get_e, :get)

  controller_obj = @controller.get(sObjectType, sUniqId, controller_params)
  data_obj = Lorj::Data.new
  data_obj.base = self
  data_obj.set(controller_obj, sObjectType) do |sObjType, oObject|
    begin
      _return_map(sObjType, oObject)
   rescue => e
     PrcLib.runtime_fail 'get %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end
  @object_data.add data_obj

  _remove_instant_config(params)

  data_obj
end

#controller_query(sObjectType, hQuery, params = nil) ⇒ Object

controller_query call lorj framework to execute a controller query task

parameters:

  • object_type: Lorj object type to use for the query.

  • params : Parameters to use for query.

returns:

  • Returns a Lorj::Data object, containing a list of Lorj::Data element.



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/core/core_controller.rb', line 145

def controller_query(sObjectType, hQuery, params = nil)
  _add_instant_config(params)

  # Check if we can re-use a previous query
  list = @object_data[:query, sObjectType]
  unless list.nil?
    if list[:query] == hQuery
      Lorj.debug(3, "Using Object '%s' query cache : %s",
                 sObjectType, hQuery)
      return list
    end
  end

  controller_params = _get_controller_params(sObjectType,
                                             :query_e, :query)
  controller_query = _query_map(sObjectType, hQuery)

  controller_obj = @controller.query(sObjectType, controller_query,
                                     controller_params)

  data_obj = Lorj::Data.new :list
  data_obj.base = self
  data_obj.set(controller_obj,
               sObjectType, hQuery) do |sObjType, key|
    begin
      _return_map(sObjType, key)
   rescue => e
     PrcLib.runtime_fail 'query %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end

  Lorj.debug(2, 'Object %s - queried. Found %s object(s).',
             sObjectType, data_obj.length)

  @object_data.add data_obj

  _remove_instant_config(params)

  data_obj
end

#controller_refresh(sObjectType, data_obj) ⇒ Object

controller_refresh call lorj framework to execute a controller refresh task

The controller must respect the following rule:

  • If the refresh was unsuccessful, due to errors, the original object should be kept intact.

  • A boolean should be return to inform that therefresh was executed successfully or not.

  • parameters:

    • object_type: Lorj object type to use for the refresh.

    • object : object to refresh.

  • returns:

    • boolean: true if refresh was executed successfully. false otherwise.



265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
# File 'lib/core/core_controller.rb', line 265

def controller_refresh(sObjectType, data_obj)
  return false unless data_obj.is_a?(Lorj::Data) && !data_obj.empty?

  controller_obj = data_obj[:object]

  is_refreshed = @controller.refresh(sObjectType, controller_obj)

  PrcLib.runtime_fail "Controller function 'refresh' must return true or "\
                      "false. Class returned: '%s'",
                      is_refreshed.class unless is_refreshed.boolean?

  Lorj.debug(1, '%s.%s - refreshed.',
             @process.class, sObjectType) if is_refreshed

  data_obj.set(controller_obj, sObjectType) do |sObjType, an_object|
    begin
      _return_map(sObjType, an_object)
   rescue => e
     PrcLib.runtime_fail 'update %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end

  is_refreshed
end

#controller_update(sObjectType, params = nil) ⇒ Object

controller_update call lorj framework to execute a controller update task

parameters:

  • object_type: Lorj object type to use for the update.

  • params : Parameters to use for update.

returns:

  • The controller must return true to inform about the real deletion



195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
# File 'lib/core/core_controller.rb', line 195

def controller_update(sObjectType, params = nil)
  _add_instant_config(params)

  # Need to detect data updated and update the Controler object with the
  # controler

  controller_params = _get_controller_params(sObjectType,
                                             :update_e, :update)

  data_obj = @object_data[sObjectType, :ObjectData]
  controller_obj = data_obj[:object]

  is_updated = false
  attributes = data_obj[:attrs]
  attributes.each do |key, value|
    attribute_obj = KeyPath.new(key)

    attribute_map = PrcLib.model.meta_obj.rh_get(sObjectType, :returns,
                                                 attribute_obj.fpath)
    attr_map_obj = KeyPath.new(attribute_map)
    old_value = @controller.get_attr(controller_obj, attr_map_obj.tree)

    next if value == old_value

    is_updated = true
    @controller.set_attr(controller_obj, attr_map_obj.tree, value)
    Lorj.debug(2, '%s.%s - Updating: %s = %s (old : %s)',
               @process.class, sObjectType, key, value, old_value)
  end

  is_done = @controller.update(sObjectType, data_obj,
                               controller_params) if is_updated

  PrcLib.runtime_fail "Controller function 'update' must return True or "\
                      "False. Class returned: '%s'",
                      is_done.class unless is_done.boolean?

  Lorj.debug(1, '%s.%s - updated.',
             @process.class, sObjectType) if is_done
  data_obj.set(controller_obj, sObjectType) do |sObjType, an_object|
    begin
      _return_map(sObjType, an_object)
   rescue => e
     PrcLib.runtime_fail 'update %s.%s : %s',
                         @process.class, sObjectType, e.message
    end
  end

  _remove_instant_config(params)

  is_done
end

#data_objects(sObjectType, *key) ⇒ Object

Function to get attributes of objects stored in the Lorj core data cache.

Args

  • object_type : Object type to get

  • *key : tree of keys to get values.

    The syntax is defined by Lorj::Data[]
    

Return

  • Value of the Lorj::Data cached key.



174
175
176
# File 'lib/core/lorj_basedefinition.rb', line 174

def data_objects(sObjectType, *key)
  @object_data[sObjectType, *key]
end

#erb(str) ⇒ Object

function to interpret a template data, and use ERBConfig as data context. ERBConfig contains config object only.



342
343
344
# File 'lib/core/definition.rb', line 342

def erb(str)
  ERB.new(str).result(@erb_config.get_binding)
end

#format_object(object_type, oMiscObject) ⇒ Object



86
87
88
89
90
91
92
93
94
95
# File 'lib/core/lorj_basedefinition.rb', line 86

def format_object(object_type, oMiscObject)
  return nil unless [String, Symbol].include?(object_type.class)

  object_type = object_type.to_sym if object_type.class == String

  { :object_type => object_type,
    :attrs => {},
    :object => oMiscObject
  }
end

#format_query(sObjectType, oControlerObject, hQuery) ⇒ Object



76
77
78
79
80
81
82
83
84
# File 'lib/core/lorj_basedefinition.rb', line 76

def format_query(sObjectType, oControlerObject, hQuery)
  {
    :object => oControlerObject,
    :object_type => :object_list,
    :list_type => sObjectType,
    :list => [],
    :query => hQuery
  }
end

#get_data(oObj, *key) ⇒ Object

get an attribute/object/… from an object.



190
191
192
193
194
195
196
197
198
# File 'lib/core/lorj_basedefinition.rb', line 190

def get_data(oObj, *key)
  if oObj.is_a?(Hash) && oObj.key?(:object_type)
    object_data = ObjectData.new
    object_data << oObj
  else
    object_data = @object_data
  end
  object_data[oObj, *key]
end

#get_data_metadata(sKey) ⇒ Object



97
98
99
# File 'lib/core/lorj_basedefinition.rb', line 97

def (sKey)
  (sKey)
end

#object_cleanup(object_type) ⇒ Object

Function to clean the cache for a specific meta lorj object.

  • Args :

    • ObjectType : Meta object type to cleanup.

  • Returns : no data

  • Raises :



181
182
183
184
185
# File 'lib/core/core_process.rb', line 181

def object_cleanup(object_type)
  object = @object_data[object_type, :ObjectData]

  @object_data.delete(object) unless object.nil?
end

#process_create(object_type, hConfig = nil) ⇒ Object

Call meta lorj object creation process. The creation process can implement any logic like:

  • create an object in the DB.

  • check object existence in the DB. If not exists, create it.

  • Args :

    • ObjectType : Meta object type to create.

    • Config : Optional. Hash containing list of data to use for

creation.

  • Returns :

  • Object : Lorj::Data object of type ObjectType created.

OR

  • Lorj::Data empty.

  • Raises :

    • Warning if the create_e process handler did not return any data. (nil)

    • Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.

    • Error if ObjectType has never been declared.

    • Error if the dependencies create_e process handler did not return any data. (nil) - Loop detection.

    • Error if the create_e process handler raise an error.



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/core/core_process.rb', line 46

def process_create(object_type, hConfig = nil)
  return nil unless object_type.is_a?(Symbol)

  _add_instant_config(hConfig)

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "%s.%s: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end
  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :create_e)

  # Check required parameters
  _process_load_dependencies(object_type, proc, :create_e, __callee__)

  # Context: Default object used
  @runtime_context[:oCurrentObj] = object_type

  if proc.nil?
    # This object is a meta object, without any data.
    # Used to build other kind of objects.
    object = Lorj::Data.new
    object.base = self
    object.set({}, object_type) {}
  else
    # build Function params to pass to the event handler.
    params = _get_process_params(object_type, :create_e, proc)
    Lorj.debug(2, "Create Object '%s' - Running '%s'", object_type, proc)

    # Call the process function.
    # At some point, the process will call the controller, via the framework
    # This controller call via the framework has the role to
    # create an ObjectData well formatted, with _return_map function
    # See Definition.connect/create/update/query/get functions (lowercase)
    object = @process.method(proc).call(object_type, params)
    # return usually is the main object that the process called should
    # provide.
    # Save Object if the object has been created by the process, without
    # controller
  end

  _remove_instant_config(hConfig)

  if object.nil?
    PrcLib.warning("'%s' has returned no data for object Lorj::Data '%s'!",
                   proc, object_type)
    Lorj::Data.new
  else
    query_cleanup(object_type)
    @object_data.add(object)
  end
end

#process_delete(object_type, hConfig = nil) ⇒ Object

Call meta lorj object deletion process There is no implementation of cascade deletion. It is up to the process to do it or not.

  • Args :

    • ObjectType : Meta object type to create.

    • Config : Optional. Hash containing list of data to use for

creation.

  • Returns :

    • Deleted : true if deleted or false otherwise.

  • Raises :

    • Warning if the create_e process handler did not return any data. (nil)

    • Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.

    • Error if ObjectType has never been declared.

    • Error if the dependencies query_e process handler did not return any data. (nil) - Loop detection.

    • Error if the query_e process handler raise an error.



119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/core/core_process.rb', line 119

def process_delete(object_type, hConfig = nil)
  return nil unless object_type.is_a?(Symbol)

  _add_instant_config(hConfig)

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "%s.%s: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end

  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :delete_e)

  if proc.nil?
    _remove_instant_config(hConfig)
    return nil
  end

  # Check required parameters
  _process_load_dependencies(object_type, proc, :delete_e, __callee__)

  # Context: Default object used.
  @runtime_context[:oCurrentObj] = object_type

  # build Function params to pass to the event handler.
  params = _get_process_params(object_type, :delete_e, proc)

  state = @process.method(proc).call(object_type, params)
  # return usually is the main object that the process called should provide

  _remove_instant_config(hConfig)

  @object_data.delete(object_type) if state
end

#process_get(object_type, sUniqId, hConfig = nil) ⇒ Object

Function to execute a get process. This function returns a Lorj::Data of type :object.

  • Args :

    • ObjectType : Meta object type to query.

    • UniqId : Uniq ID.

    • Config : Optional. Hash containing list of data to use for

      getting.
      
  • Returns :

  • Lorj::Data of type :object

OR

  • Lorj::Data empty.

  • Raises :

    • Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.

    • Error if ObjectType has never been declared.

    • Error if the dependencies get_e process handler did not return any data. (nil) - Loop detection.

    • Error if the get_e process handler raise an error.



294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
# File 'lib/core/core_process.rb', line 294

def process_get(object_type, sUniqId, hConfig = nil)
  return nil unless object_type.is_a?(Symbol)

  _add_instant_config(hConfig)

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "$s.: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end

  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :get_e)

  if proc.nil?
    _remove_instant_config(hConfig)
    return nil
  end

  # Check required parameters
  _process_load_dependencies(object_type, proc, :get_e, __callee__)

  # Context: Default object used
  @runtime_context[:oCurrentObj] = object_type

  # build Function params to pass to the Process Event handler.
  params = _get_process_params(object_type, :get_e, proc)

  # Call the process function.
  # At some point, the process will call the controller, via the framework.
  # This controller call via the framework has the role to
  # create an ObjectData well formatted, with _return_map function
  # See Definition.connect/create/update/query/get functions (lowercase)
  object = @process.method(proc).call(object_type, sUniqId, params)
  # return usually is the main object that the process called should provide

  _remove_instant_config(hConfig)

  if object.nil?
    PrcLib.warning("'%s' has returned no data for object Lorj::Data '%s'!",
                   proc, object_type)
    Lorj::Data.new
  else
    @object_data.add(object)
  end
end

#process_query(object_type, hQuery, hConfig = nil) ⇒ Object

Function to execute a query process. This function returns a Lorj::Data of type :list.

  • Args :

    • ObjectType : Meta object type to query.

    • Query : Hash. Represent the query to execute.

    • Config : Optional. Hash containing list of data to use for query

  • Returns : Lorj::Data of type :list

OR

  • Lorj::Data empty.

  • Raises :



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/core/core_process.rb', line 203

def process_query(object_type, hQuery, hConfig = nil)
  return nil unless object_type.is_a?(Symbol)

  _add_instant_config(hConfig)

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "%s.%s: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end

  # Check if we can re-use a previous query
  list = query_cache(object_type, hQuery)
  unless list.nil?
    _remove_instant_config(hConfig)
    return list
  end

  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :query_e)

  if proc.nil?
    _remove_instant_config(hConfig)
    return nil
  end

  # Check required parameters
  _process_load_dependencies(object_type, proc, :query_e, __callee__)

  # Context: Default object used.
  @runtime_context[:oCurrentObj] = object_type

  # build Function params to pass to the Process Event handler.
  params = _get_process_params(object_type, :query_e, proc)

  # Call the process function.
  # At some point, the process will call the controller, via the framework.
  # This controller call via the framework has the role to
  # create an ObjectData well formatted, with _return_map function
  # See Definition.connect/create/update/query/get functions (lowercase)
  object = @process.method(proc).call(object_type, hQuery, params)

  _remove_instant_config(hConfig)

  # return usually is the main object that the process called should provide
  if object.nil?
    PrcLib.warning("'%s' returned no collection of objects Lorj::Data "\
                   "for '%s'", proc, object_type)
    Lorj::Data.new
  else
    # Save Object if the object has been created by the process, without
    # controller
    @object_data.add(object)
  end
end

#process_refresh(object) ⇒ Object

Function to execute an object update. This function returns a Lorj::Data of type :object, refreshed.

It uses the event ‘refresh_e’. If not defined, the refresh is simply not executed. No warning exposed, but a debug info is thrown.

refresh_e is defined and called as follow:

BaseDefinition class derived function. This Process function should do any task required to execute a refresh of the object passed. The controller object data should be extracted by the controller_refresh call to refresh :attrs. See #controller_refresh. It should return true or false if the object refresh was done successfully or not

It is possible to call directly the controller_refresh as the process event

  • args:

    • object_type: The object_type to refresh

    • object : The Lorj::Data object to refresh

  • returns:

    • boolean : true if refresh was executed successfully. false otherwise.

From the object itself, you can call object.refresh. This will call this function.

The controller event usually called is controller_refresh.

  • Args :

    • object_type : Meta object type to query.

    • config : Optional. Hash containing list of data to use for

updating.

  • Returns :

    • boolean : true if the refresh was executed successfully. false otherwise.

  • Raises :

    • Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.

    • Error if ObjectType has never been declared.

    • Error if the dependencies get_e process handler did not return any data. (nil) - Loop detection.

    • Error if the get_e process handler raise an error.



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
# File 'lib/core/core_process.rb', line 447

def process_refresh(object)
  return nil unless object.is_a?(Lorj::Data) && object.type == :object &&
                    !object.empty?

  object_type = object.object_type?

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "$s.%s: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end

  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :refresh_e)

  if proc.nil?
    Lorj.debug(1, "No 'refresh_e' event found for object type '%s'",
               object_type)
    return false
  end

  ret = @process.method(proc).call(object_type, object)

  unless ret.boolean?
    Lorj.debug(1, "'%s' has not returned a boolean. Consider return false.",
               object_type)
    ret = false
  end
  ret
end

#process_setup(sObjectType) ⇒ Object

Setup process. The setup process is used to ask the end user to provide some data. You can call it before you run an action, or during a configution setting of your application.

setup will be exposed to the end user per several steps, and config data to ask in a specific order, with optionnally some explanations, possible values (hard coded list of values or queried from the model) and default value.

Ex: Step 1 description : *Provider configuration*: explanation : You are going to setup your account information

ask a config data: Enter my account name:  |myuser|
ask others data  : Enter ...

Step 2 description : *Another configuration to setup*:

ask several data : Enter ...

etc…

Steps are predefined in the application defaults.yaml from /:setup/:ask_step Commonly, each step can define the following options:

  • :desc: Required. Define the step description.

    ERB template enable. To get config data,
    type <%= config[...] %>
    
  • :explanation: |- Optional. Define a multiline explanation. This is

    printed out in brown color.
    ERB template enable. To get config data, type
    <%= config[...] %>
    

For details or more options, see core_model.rb

config data are initially identified by the Object model dependency. (See obj_needs model declaration.)

The ‘object_type’ passed as parameter is the top level object in object dependency. each config data are sorted by object dependencies and additionnal options defined in the application defaults.yaml at: /:section/<section name>/<data>/ See lib/core/code_model.rb

setup will ask only data which are configured with :account => true /:section/<section name>/<data>/:account => true

Additional config data can added to the list thanks to: /:setup/:ask_step/:add/

Commonly, each data can define the following options:

  • :account: Optional. default: False

    => setup will ask the data only if :account is true
    
  • :desc: Required if :account is true. String. default: nil

    => Description
    
  • :explanation: |- Print a multiline explanation before asking the data

    ERB template enable. To get config data,
    type <%= config[...] %>
    
  • :ask_sort: Number sort position.

  • :after: Name of the previous <Data> to ask before the

    current one.
    
  • :depends_on: Additional data dependency.

  • :default_value: Default value at setup time.

  • :validate: Regular expression to validate end user input

    during setup.
    
  • :list_values: Additional options to get a list of possible values.

  • :post_step_function Function to call after data asked to the user. This function must return a boolean:

    • true : The data is accepted and setup will go further.

    • false: The data is NOT accepted and setup will ask the data again. setup will loop until the function is happy with (return true)

  • :pre_step_function Function to call before data is asked to the user. This function must return a boolean:

    • true : setup will ask the data.

    • false: setup will skip asking the data.

For details or more options, see core_model.rb

Setup is based on a config object which requires to have at least following functions:

  • value = get(key, default)

  • set(key, value)

You can create you own config class, derived from Lorj::Config.

When setup has done to ask data to the user, the config object is updated. It is up to you and your application to decide what you want to do with those data. Usually, if your application uses setup to setup an account settings Lorj::Account or some local application defaults Lorj::Config, you may want to save them to a configuration file. If you are using Lorj::Account, use function ac_save If you are using Lorj::Config, use function config_save

  • Args :

    • ObjectType : Top object type to ask.

  • Returns :

    • nothing.

  • Raises :



127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/core/core_process_setup.rb', line 127

def process_setup(sObjectType)
  unless PrcLib.model.meta_obj.rh_exist?(sObjectType)
    PrcLib.runtime_fail "Setup: '%s' not a valid object type."
  end

  Lorj.debug(2, "Setup is identifying account data to ask for '%s'",
             sObjectType)
  # Loop in dependencies to get list of data object to setup
  setup_steps = _setup_identify(sObjectType, _setup_load)

  Lorj.debug(2, 'Setup check if needs to add unrelated data in the process')
  _setup_check_additional(setup_steps)

  Lorj.debug(2, "Setup will ask for :\n %s", setup_steps.to_yaml)

  _setup_ask(setup_steps)

  PrcLib.info("Configuring account : '#{config[:name]}',"\
              " provider '#{config[:provider]}'")
end

#process_update(object_type, hConfig = nil) ⇒ Object

Function to execute a update process. This function returns a Lorj::Data of type :object.

  • Args :

    • object_type : Meta object type to query.

    • config : Optional. Hash containing list of data to use for

updating.

  • Returns :

    • Lorj::Data of type :object

    OR

    • Lorj::Data empty.

  • Raises :

    • Warning if the Config data passed are not required by the meta object (or dependencies) at creation time.

    • Error if ObjectType has never been declared.

    • Error if the dependencies get_e process handler did not return any data. (nil) - Loop detection.

    • Error if the get_e process handler raise an error.



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/core/core_process.rb', line 360

def process_update(object_type, hConfig = nil)
  return nil unless object_type.is_a?(Symbol)

  _add_instant_config(hConfig)

  unless PrcLib.model.meta_obj.rh_exist?(object_type)
    PrcLib.runtime_fail "$s.%s: '%s' is not a known object type.",
                        self.class, __callee__, object_type
  end

  proc = PrcLib.model.meta_obj.rh_get(object_type, :lambdas, :update_e)

  if proc.nil?
    _remove_instant_config(hConfig)
    return nil
  end

  _process_load_dependencies(object_type, proc, :update_e, __callee__)

  # Context: Default object used.
  @runtime_context[:oCurrentObj] = object_type

  # build Function params to pass to the event handler.
  params = _get_process_params(object_type, :update_e, proc)

  object = @process.method(proc).call(object_type, params)
  # return usually is the main object that the process called should provide

  _remove_instant_config(hConfig)

  if object.nil?
    PrcLib.warning("'%s' has returned no data for object Lorj::Data '%s'!",
                   proc, object_type)
    Lorj::Data.new
  else
    @object_data.add(object)
  end
end

#query_cache(object_type, hQuery) ⇒ Object



257
258
259
260
261
262
263
264
265
266
267
268
269
270
# File 'lib/core/core_process.rb', line 257

def query_cache(object_type, hQuery)
  # Check if we can re-use a previous query
  list = @object_data[:query, object_type]

  return if list.nil?

  if list[:query] == hQuery
    Lorj.debug(3, "Using Object '%s' query cache : %s",
               object_type, hQuery)
    return list
  end

  nil
end

#query_cleanup(object_type) ⇒ Object

Function to clean the cache for a specific meta lorj object queried.

  • Args :

    • ObjectType : Meta object type to cleanup.

  • Returns : no data

  • Raises :



163
164
165
166
167
168
169
# File 'lib/core/core_process.rb', line 163

def query_cleanup(object_type)
  list = @object_data[:query, object_type]
  return if list.nil?

  @object_data.delete(list)
  Lorj.debug(2, "Query cache for object '%s' cleaned.", object_type)
end

#register(oObject, sObjectType = nil, sDataType = :object) ⇒ Object

Register the object to the internal @object_data instance



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/core/lorj_basedefinition.rb', line 148

def register(oObject, sObjectType = nil, sDataType = :object)
  if oObject.is_a?(Lorj::Data)
    data_objects = oObject
  else
    PrcLib.runtime_fail "Unable to register an object '%s' "\
                         'as Lorj::Data object if ObjectType is not given.',
                        oObject.class unless sObjectType
    data_objects = Lorj::Data.new(sDataType)
    data_objects.base = self
    data_objects.set(oObject, sObjectType) do |sObjType, oControlerObject|
      _return_map(sObjType, oControlerObject)
    end
  end
  @object_data.add data_objects
end

#update_params(data_to_refresh, refresh_par) ⇒ Object

function to update an existing ObjectData used as parameters to process or controller

parameters:

  • data_to_refresh: ObjectData to refresh

  • refresh_par : Hash providing the parameter context used to refresh it

return:

  • data refreshed.



32
33
34
35
36
37
38
39
# File 'lib/core/core_object_params.rb', line 32

def update_params(data_to_refresh, refresh_par) # :nodoc:
  object_type = refresh_par[:object_type]
  event_type = refresh_par[:event_type]
  as_controller = refresh_par[:controller]

  _get_object_params(object_type, event_type, __callee__, as_controller,
                     data_to_refresh)
end