lorj 1.0.10 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,7 +40,8 @@ module Lorj
40
40
  # * *Raises* :
41
41
  #
42
42
  def _setup_list_from_controller_call(obj_to_load, list_options, default)
43
- PrcLib.message("Loading #{obj_to_load}.")
43
+ PrcLib.message("Loading :object #{obj_to_load}.")
44
+ Lorj.debug(3, ':query_type = :controller_call')
44
45
 
45
46
  object = @object_data[obj_to_load, :ObjectData]
46
47
  object = process_create(obj_to_load) if object.nil?
@@ -78,7 +79,8 @@ module Lorj
78
79
  # * *Raises* :
79
80
  #
80
81
  def _setup_list_from_query_call(obj_to_load, list_options, default)
81
- PrcLib.message("Querying #{obj_to_load}.")
82
+ PrcLib.message("Querying :object #{obj_to_load}.")
83
+ Lorj.debug(3, ':query_type = :query_call - ')
82
84
 
83
85
  query_hash = list_options[:query_params]
84
86
  query_hash = {} if query_hash.nil?
@@ -126,7 +128,8 @@ module Lorj
126
128
  data if list_options[:query_call].nil?
127
129
  proc = list_options[:query_call]
128
130
  obj_to_load = list_options[:object]
129
- Lorj.debug(2, "Running process '#{proc}' on '#{obj_to_load}'.")
131
+ PrcLib.message("Running process '#{proc}' on :object '#{obj_to_load}'.")
132
+ Lorj.debug(3, ':query_type = :process_call')
130
133
 
131
134
  # Building Process function attr_params parameter
132
135
  params = ObjectData.new
@@ -289,9 +289,9 @@ module Lorj
289
289
 
290
290
  PrcLib.model.data_context data
291
291
 
292
- section = Lorj.data.first_section(data.key)
292
+ section, key = Lorj.data.first_section(data.key)
293
293
 
294
- Lorj.data.define_controller_data(section, data.key, options)
294
+ Lorj.data.define_controller_data(section, key, options)
295
295
  end
296
296
 
297
297
  # Controller to declare a model Data value mapping
@@ -37,7 +37,7 @@ module Lorj
37
37
 
38
38
  def _get_account_section(key)
39
39
  return nil if key.nil?
40
- Lorj.data.first_section(key)
40
+ Lorj.data.first_section(key)[0]
41
41
  end
42
42
 
43
43
  # internal runtime function for process call
@@ -35,6 +35,12 @@ module Lorj
35
35
  }
36
36
 
37
37
  @config = oForjConfig
38
+
39
+ @data = Lorj.data # Get data definition object
40
+ # data object is currently built by
41
+ # - global application defaults.yaml loaded in @config.
42
+ # - process data.yaml files
43
+
38
44
  @erb_config = ERBConfig.new(oForjConfig)
39
45
  if !oForjConfig.is_a?(Lorj::Account) && !oForjConfig.is_a?(Lorj::Config)
40
46
  PrcLib.runtime_fail "'%s' is not a valid ForjAccount or ForjConfig"\
data/lib/core/process.rb CHANGED
@@ -24,9 +24,40 @@ module Lorj
24
24
  class ProcessResource
25
25
  attr_reader :defaults_file, :data_file, :process, :name, :controllers
26
26
 
27
+ # ProcessResource initialization
28
+ #
29
+ # Create a ProcessResource Instance with resource data.
30
+ #
31
+ # * *Args*:
32
+ # - +name+ : Name of the process
33
+ # - +path+ : Process path
34
+ # By default the process path will search for:
35
+ # - <name>_process.rb : Main process file
36
+ # - <name>/controllers/<controller>/<controller>.rb : controllers list
37
+ # attached to the process `name`.
38
+ # - <name>/defaults.yaml : defaults process values
39
+ # (under section :defaults)
40
+ # - <name>/data.yaml : Process data definition
41
+ #
42
+ # You can redefine some defaults, with `props` Hash argument.
43
+ #
44
+ # - :controllers_dir : Change the name of the controllers directory.
45
+ # Default is `controllers`
46
+ # - :controllers_path: Change the complete path to search for controllers
47
+ # By default is `<name>/controllers`
48
+ # - :defaults_file : Use a different file as process defaults.
49
+ # By default is `<name>/defaults.yaml`
50
+ # - :data_file : Use a different file as process data definition.
51
+ # By default is `<name>/data.yaml`
52
+ #
53
+ # * *return*:
54
+ # - self with at least a process name and a path to it.
55
+ #
56
+ # If any data are invalid, the process name will be set to nil.
27
57
  def initialize(name, path, props = {})
28
- # Determine resources
29
- name = name.to_s if name.is_a?(Symbol)
58
+ name, path, props = _validate_parameters(name, path, props)
59
+
60
+ return if name.nil?
30
61
 
31
62
  process_path = File.expand_path(File.join(path, 'process',
32
63
  name + '_process.rb'))
@@ -37,22 +68,50 @@ module Lorj
37
68
 
38
69
  controller_dir = 'controllers'
39
70
  controller_dir = props[:controllers_dir] if props.key?(:controllers_dir)
40
- controller_path = File.expand_path(File.join(path, controller_dir))
71
+ ctrls_path = File.expand_path(File.join(path, 'process', name,
72
+ controller_dir))
41
73
 
42
- _identify_controllers(controller_path)
74
+ _identify_controllers(_get_value(props, :controllers_path, ctrls_path))
43
75
 
44
- defaults_file = File.expand_path(File.join(path, 'defaults.yaml'))
45
- @defaults_file = defaults_file if File.exist?(defaults_file)
76
+ defaults_file = _get_file(props, :defaults_file,
77
+ File.join(path, 'process',
78
+ name, 'defaults.yaml'))
79
+ @defaults_file = defaults_file if defaults_file
46
80
 
47
- data_file = File.expand_path(File.join(path, 'data.yaml'))
48
- @data_file = data_file if File.exist?(data_file)
81
+ data_file = _get_file(props, :data_file, File.join(path, 'process',
82
+ name, 'data.yaml'))
83
+ @data_file = data_file if data_file
49
84
 
50
85
  self
51
86
  end
52
87
 
53
88
  private
54
89
 
90
+ def _get_value(props, key, default)
91
+ return props[key] if props.key?(key)
92
+ default
93
+ end
94
+
95
+ def _get_file(props, key, filename)
96
+ file = File.expand_path(filename)
97
+ file = _get_value(props, key, file)
98
+ return file if File.exist?(file)
99
+ end
100
+
101
+ # Ensure parameters are correct
102
+ def _validate_parameters(name, path, props)
103
+ return unless [String, Symbol].include?(name.class) && path.is_a?(String)
104
+
105
+ props = {} unless props.is_a?(Hash)
106
+
107
+ # Determine resources
108
+ name = name.to_s if name.is_a?(Symbol)
109
+ [name, path, props]
110
+ end
111
+
55
112
  def _identify_controllers(controller_path)
113
+ return unless File.directory?(controller_path)
114
+
56
115
  @controllers = {}
57
116
 
58
117
  Dir.foreach(controller_path) do |dir|
data/lib/logging.rb CHANGED
@@ -191,11 +191,15 @@ module PrcLib
191
191
  # Create a Logging object if missing and return it.
192
192
  # Used internally by other functions
193
193
  def log_object
194
- if PrcLib.log.nil?
195
- PrcLib.log = PrcLib::Logging.new
196
- else
197
- PrcLib.log
198
- end
194
+ PrcLib.log = PrcLib::Logging.new if PrcLib.log.nil?
195
+ PrcLib.log
196
+ end
197
+
198
+ def log_object=(logger)
199
+ return PrcLib.log unless logger.is_a?(Logger)
200
+
201
+ PrcLib.log = logger if PrcLib.log.nil?
202
+ PrcLib.log
199
203
  end
200
204
 
201
205
  # Print out a message, not logged in the log file. This message is printed out
data/lib/lorj/version.rb CHANGED
@@ -16,6 +16,6 @@
16
16
 
17
17
  # Lorj version
18
18
  module Lorj
19
- VERSION = '1.0.10'
20
- DATE = '2015-04-17'
19
+ VERSION = '1.0.11'
20
+ DATE = '2015-05-20'
21
21
  end
data/lib/lorj_account.rb CHANGED
@@ -197,11 +197,13 @@ module Lorj
197
197
  options = {} unless options.is_a?(Hash)
198
198
 
199
199
  section = options[:section]
200
- section = Lorj.data.first_section(key) if section.nil?
200
+ section, key = Lorj.data.first_section(key) if section.nil?
201
201
 
202
- options = options.merge(:keys => [key], :section => section)
202
+ options = options.merge(:keys => [key])
203
+ options.delete(:section)
203
204
 
204
205
  indexes = _identify_indexes(options, exclusive?(key, section))
206
+
205
207
  names = []
206
208
  indexes.each { |index| names << @config_layers[index][:name] }
207
209
 
@@ -246,7 +248,7 @@ module Lorj
246
248
  options = {} unless options.is_a?(Hash)
247
249
 
248
250
  section = options[:section]
249
- section = Lorj.data.first_section(key) if section.nil?
251
+ section, key = Lorj.data.first_section(key) if section.nil?
250
252
 
251
253
  indexes = _identify_indexes(options, exclusive?(key, section))
252
254
 
@@ -255,7 +257,6 @@ module Lorj
255
257
 
256
258
  where_options = {
257
259
  :keys => [key],
258
- :section => section,
259
260
  :indexes => indexes,
260
261
  :data_options => _set_data_options_per_names(names, section)
261
262
  }
@@ -292,8 +293,9 @@ module Lorj
292
293
  options = {} unless options.is_a?(Hash)
293
294
 
294
295
  section = options[:section]
295
- section = Lorj.data.first_section(key) if section.nil?
296
- options = options.merge(:keys => [key], :section => section)
296
+ section, key = Lorj.data.first_section(key) if section.nil?
297
+ options = options.merge(:keys => [key])
298
+ options.delete(:section)
297
299
 
298
300
  indexes = _identify_indexes(options, exclusive?(key, section))
299
301
 
@@ -323,6 +325,7 @@ module Lorj
323
325
 
324
326
  key = key.to_sym if key.class == String
325
327
  section = Lorj.defaults.get_meta_section(key) if section.nil?
328
+ section, key = _detect_section(key, section)
326
329
 
327
330
  return nil if section.nil?
328
331
 
@@ -349,7 +352,7 @@ module Lorj
349
352
  return nil unless key
350
353
 
351
354
  key = key.to_sym if key.class == String
352
- section = Lorj.data.first_section(key) if section.nil?
355
+ section, key = Lorj.data.first_section(key) if section.nil?
353
356
 
354
357
  return nil if section.nil?
355
358
  result = Lorj.data[:sections, section, key, :account_exclusive]
@@ -386,9 +389,10 @@ module Lorj
386
389
  return nil if parameters.nil?
387
390
 
388
391
  key = parameters[0][0]
389
- layer_name, section = parameters[1]
392
+ layer_name, section = parameters[1][0]
390
393
 
391
- section = Lorj.data.first_section(key) if section.nil?
394
+ found_section, key = Lorj.data.first_section(key)
395
+ section = found_section if section.nil?
392
396
  section = :default if section.nil?
393
397
 
394
398
  return nil if readonly?(key, section)
@@ -439,6 +443,7 @@ module Lorj
439
443
 
440
444
  section = Lorj.defaults.get_meta_section(key) if section.nil?
441
445
  section = :default if section.nil?
446
+ section, key = _detect_section(key, section)
442
447
 
443
448
  return nil if readonly?(key, section)
444
449
 
@@ -544,6 +549,12 @@ module Lorj
544
549
 
545
550
  private
546
551
 
552
+ def _detect_section(key, default_section)
553
+ m = key.to_s.match(/^(.*)#(.*)$/)
554
+ return [m[1].to_sym, m[2].to_sym] if m && m[1] != '' && m[2] != ''
555
+ [default_section, key]
556
+ end
557
+
547
558
  def _identify_array_indexes(options, account_exclusive)
548
559
  def_indexes = options[:indexes] if options.key?(:indexes)
549
560
  if options[:names].is_a?(Array)
@@ -571,8 +582,9 @@ module Lorj
571
582
  end
572
583
 
573
584
  def exclusive_indexes(account_exclusive)
574
- return [0, 1] if account_exclusive
575
- [0, 1, 2, 3, 4]
585
+ return layer_indexes { true } unless account_exclusive
586
+
587
+ layer_indexes { |n, _i| %w(runtime account).include?(n[:name]) }
576
588
  end
577
589
 
578
590
  def _identify_indexes(options, account_exclusive)
@@ -588,6 +600,9 @@ module Lorj
588
600
  indexes
589
601
  end
590
602
 
603
+ # Internal functions to generate the list of options
604
+ # for each layer name.
605
+ # The names order needs to be kept in options.
591
606
  def _set_data_options_per_names(names, section)
592
607
  data_options = []
593
608
 
@@ -608,16 +623,21 @@ module Lorj
608
623
  # local & default are SectionConfig and is forced to use :default as
609
624
  # section name for each data.
610
625
  return { :section => :default }
626
+ when 'account'
627
+ # If no section is provided, 'account' layer will use the first section
628
+ # name
629
+ # otherwise, it will used the section provided.
630
+ # account is a SectionConfig and use section value defined by the
631
+ # lorj data model. So the section name is not forced.
632
+ return { :section => section } unless section.nil?
633
+ return nil
611
634
  end
612
- # nil: layer_index = 0 => runtime. runtime is not a SectionConfig.
613
-
614
- # nil: layer_index = 1 => account
615
- # If no section is provided, 'account' layer will use the first section
616
- # name
617
- # otherwise, it will used the section provided.
618
- return { :section => section } unless section.nil?
619
- # account is a SectionConfig and use section value defined by the
620
- # lorj data model. So the section name is not forced.
635
+ # For SectionsConfig layer, :default is automatically set.
636
+ # Except if there is later a need to set a section, nil is enough.
637
+ # For BaseConfig, no options => nil
638
+ #
639
+ # Process/controller layers are SectionsConfig
640
+ # others (runtime/instant) are BaseConfig.
621
641
  nil
622
642
  end
623
643
 
data/lib/lorj_config.rb CHANGED
@@ -202,12 +202,17 @@ module Lorj
202
202
  # * *Args* :
203
203
  # - +key+ : key name. Can be an key tree (Array of keys).
204
204
  # - +value+ : Value to set
205
+ # - +options+ : possible options:
206
+ # - +:name+ : layer to exclusively set data.
207
+ # - +:index+ : layer index to exclusively set data.
208
+ # If neither :name or :index is set, set will use the 'runtime' layer.
209
+ #
205
210
  # * *Returns* :
206
211
  # - value set
207
212
  # * *Raises* :
208
213
  # Nothing
209
- def set(key, value)
210
- self[key] = value # Call PRC::CoreConfig [] function
214
+ def set(key, value, options = {})
215
+ p_set(options.merge(:keys => [key], :value => value))
211
216
  end
212
217
 
213
218
  # Get function
data/lib/lorj_defaults.rb CHANGED
@@ -228,9 +228,12 @@ module Lorj
228
228
  def get_meta_section(key)
229
229
  PrcLib.debug("'Lorj.defaults.%s' is obsolete and will be removed "\
230
230
  'in Lorj 2.0. Please update your code to call '\
231
- "'Lorj.data.%s' instead.\n%s",
232
- __method__, 'first_section', caller[0])
233
- Lorj.data.first_section(key)
231
+ "'Lorj.data.%s' instead.\n%s. Warning! This function call "\
232
+ "return is different than 'Lorj.defaults.%s'. Please read "\
233
+ 'the documentation',
234
+ __method__, 'first_section', caller[0], __method__)
235
+ section, = Lorj.data.first_section(key)
236
+ section
234
237
  end
235
238
 
236
239
  #
@@ -243,7 +246,7 @@ module Lorj
243
246
  # - ++ ->
244
247
  def load
245
248
  if !PrcLib.app_defaults
246
- PrcLib.warning('PrcLib.app_defaults is not set. Application defaults'\
249
+ PrcLib.debug('PrcLib.app_defaults is not set. Application defaults'\
247
250
  " won't be loaded.")
248
251
  else
249
252
  @filename = File.join(PrcLib.app_defaults, 'defaults.yaml')
data/lib/lorj_meta.rb CHANGED
@@ -50,6 +50,15 @@ module Lorj
50
50
  p_set(:keys => [:keys], :value => section_map, :name => 'map')
51
51
  end
52
52
 
53
+ # Implement a section detection in a symbol/string
54
+ # Help each auto_* functions to work without update.
55
+ #
56
+ def _detect_section(key, default_section)
57
+ m = key.to_s.match(/^(.*)#(.*)$/)
58
+ return [m[1].to_sym, m[2].to_sym] if m && m[1] != '' && m[2] != ''
59
+ [default_section, key]
60
+ end
61
+
53
62
  # set section data mapping
54
63
  #
55
64
  def update_map(section, data)
@@ -322,7 +331,11 @@ module Lorj
322
331
  #
323
332
  # - :object:
324
333
  #
325
- # Used with :query_type=:query_call. object type symbol to query.
334
+ # - When used with :query_type == :query_call or :controller_call,
335
+ # :object is the object type symbol to query.
336
+ #
337
+ # - When used with :query_type == :process_call, :object is the
338
+ # object used in the process.
326
339
  #
327
340
  # - :query
328
341
  #
@@ -380,6 +393,22 @@ module Lorj
380
393
  build_section_mapping
381
394
  end
382
395
 
396
+ # Redefine CoreConfig#layer_add to add mapping build
397
+ #
398
+ # See CoreConfig#layer_add for details
399
+ def layer_add(options)
400
+ p_layer_add(options)
401
+ build_section_mapping
402
+ end
403
+
404
+ # Redefine CoreConfig#layer_remove to add mapping build
405
+ #
406
+ # See CoreConfig#layer_remove for details
407
+ def layer_remove(options)
408
+ p_layer_remove(options)
409
+ build_section_mapping
410
+ end
411
+
383
412
  # Loop on Config metadata
384
413
  #
385
414
  # * *Args* :
@@ -390,6 +419,12 @@ module Lorj
390
419
  def meta_each
391
420
  data = p_get(:keys => [:sections], :merge => true)
392
421
 
422
+ if data.nil?
423
+ PrcLib.warning('No model data definition found. Do you have a model'\
424
+ ' loaded?')
425
+ return
426
+ end
427
+
393
428
  data.each do |section, hValue|
394
429
  hValue.each do |key, value|
395
430
  yield section, key, value
@@ -414,35 +449,42 @@ module Lorj
414
449
  # If a key name is found in several different section,
415
450
  #
416
451
  # auto_* functions, usually, will get the first section
417
- # from a key/sections mapping Array.
452
+ # from a key/sections mapping Array except if you provide
453
+ # a '#' in the data name. (Ex: :'section1#key1')
418
454
  #
419
455
  # The list of sections for one key is build thanks to
420
456
  # build_section_mapping.
421
457
  #
422
458
  # * *Args* :
423
- # - +data+ : data name to check
459
+ # - +data+ : data name to check. Support 'section#data'.
424
460
  #
425
461
  # * *Returns* :
426
462
  # - true/false
427
463
  def auto_meta_exist?(data)
428
464
  return nil unless data
429
465
 
430
- section = first_section(data)
466
+ section, data = first_section(data)
467
+
431
468
  p_exist?(:keys => [:sections, section, data])
432
469
  end
433
470
 
434
- # return the 1st section name of a data.
471
+ # return the 1st section name found of a data or the section discovered.
435
472
  #
436
473
  # * *Args* :
437
- # - +data+ : data name to search
474
+ # - +data+ : data name to search. It supports section#name.
438
475
  #
439
476
  # * *Returns* :
440
- # - 1st section name found.
477
+ # - Array:
478
+ # - section name
479
+ # - key name
441
480
  def first_section(data)
442
- return nil unless p_exist?(:keys => [:keys, data])
481
+ section, data = _detect_section(data, nil)
482
+ return [section, data] unless section.nil? &&
483
+ p_exist?(:keys => [:keys, data])
484
+
443
485
  arr = p_get(:keys => [:keys, data])
444
486
  return nil unless arr.is_a?(Array) && arr[0]
445
- arr[0]
487
+ [arr[0], data]
446
488
  end
447
489
 
448
490
  # return the list of sections name of a data.
@@ -456,6 +498,7 @@ module Lorj
456
498
  def sections(data = nil)
457
499
  return p_get(:keys => [:sections]).keys if data.nil?
458
500
 
501
+ _, data = _detect_section(data, nil)
459
502
  return nil unless p_exist?(:keys => [:keys, data])
460
503
  p_get(:keys => [:keys, data])
461
504
  end
@@ -492,7 +535,7 @@ module Lorj
492
535
  p_get(:keys => keys, :merge => true)
493
536
  end
494
537
 
495
- # Get setup options. It returns the the top layer data for options requested
538
+ # Get setup options. It returns the top layer data for options requested
496
539
  #
497
540
  # * *Args* :
498
541
  # - +options+ : Array of options tree.
@@ -506,7 +549,7 @@ module Lorj
506
549
  def setup_data(*options)
507
550
  keys = [:setup]
508
551
  keys.concat(options)
509
- p_get(:keys => keys)
552
+ p_get(:keys => keys, :merge => true)
510
553
  end
511
554
 
512
555
  # Get model section/data options. It returns the list of options, against
@@ -515,7 +558,7 @@ module Lorj
515
558
  # * *Args* :
516
559
  # - +section+ : section name
517
560
  # - +data+ : data name
518
- # - +options+ : options tree.
561
+ # - +options+ : Optionnal. List of sub keys in tree to get data.
519
562
  #
520
563
  # * *Returns* :
521
564
  # - Merged cloned data options values.
@@ -537,14 +580,16 @@ module Lorj
537
580
  # data name
538
581
  #
539
582
  # auto_* functions, usually, will get the first section
540
- # from a key/sections mapping Array.
583
+ # from a key/sections mapping Array. But it supports also 'Section#Name' to
584
+ # determine the section to use instead of first one.
585
+ #
541
586
  #
542
587
  # The list of sections for one key is build thanks to
543
588
  # build_section_mapping.
544
589
  #
545
590
  # * *Args* :
546
- # - +data+ : data name
547
- # - options+ : options tree.
591
+ # - +data+ : data name. Support 'Section#Name'
592
+ # - +options+ : Optionnal. List of sub keys in tree to get data.
548
593
  # * *Returns* :
549
594
  # - data options values
550
595
  # OR
@@ -554,7 +599,7 @@ module Lorj
554
599
  #
555
600
  def auto_section_data(data, *options)
556
601
  return nil if data.nil?
557
- section = first_section(data)
602
+ section, data = first_section(data)
558
603
  section_data(section, data, *options)
559
604
  end
560
605
 
File without changes
@@ -0,0 +1,42 @@
1
+ # (c) Copyright 2014 Hewlett-Packard Development Company, L.P.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Defaults yaml file used for rspec.
16
+ :default:
17
+ :maestro_url: http://example.org
18
+ :keypair_name: default_key
19
+ :data: None
20
+ :default_case2: 'success'
21
+ :description:
22
+ :FORJ_HPC: Testing extra application default value.
23
+ :setup:
24
+ - :desc: 'Step 1'
25
+ :explanation: |-
26
+ My complete explanation is in
27
+ multiline <%= config['text'] %>
28
+ - :desc: 'Step 2'
29
+ :add:
30
+ - :data
31
+ :sections:
32
+ :credentials:
33
+ :keypair_name:
34
+ :data:
35
+ :account_exclusive: true
36
+ :maestro:
37
+ :maestro_url:
38
+ :lorj_default:
39
+ :default_case:
40
+ :default_value: 'success'
41
+ :default_case2:
42
+ :default_value: 'incorrect - meta-default value'
@@ -15,7 +15,7 @@
15
15
  # limitations under the License.
16
16
 
17
17
  # Students process
18
- class StudentsProcess
18
+ class MockProcess
19
19
  def create_student(sObjectType, hParams)
20
20
  PrcLib.state(format("Running creation process for object '%s' = '%s'",
21
21
  sObjectType, hParams[:student_name]))