marty 2.3.15 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +2 -2
  3. data/app/components/marty/api_auth_view.rb +27 -4
  4. data/app/components/marty/api_config_view.rb +27 -4
  5. data/app/components/marty/extras/layout.rb +4 -7
  6. data/app/components/marty/form.rb +8 -0
  7. data/app/components/marty/grid.rb +45 -19
  8. data/app/components/marty/main_auth_app.rb +12 -11
  9. data/app/controllers/marty/rpc_controller.rb +63 -150
  10. data/app/models/marty/api_auth.rb +86 -14
  11. data/app/models/marty/api_config.rb +11 -6
  12. data/app/models/marty/delorean_rule.rb +3 -2
  13. data/config/routes.rb +1 -1
  14. data/db/migrate/501_add_api_class_to_marty_api_config.rb +6 -0
  15. data/db/migrate/502_add_parameters_to_marty_api_auth.rb +5 -0
  16. data/lib/marty/util.rb +0 -15
  17. data/lib/marty/version.rb +1 -1
  18. data/other/marty/api/base.rb +207 -0
  19. data/other/marty/diagnostic/aws/ec2_instance.rb +12 -87
  20. data/other/marty/diagnostic/environment_variables.rb +1 -1
  21. data/spec/controllers/job_controller_spec.rb +1 -1
  22. data/spec/dummy/app/components/gemini/xyz_rule_view.rb +1 -0
  23. data/spec/dummy/config/application.rb +1 -0
  24. data/spec/features/enum_spec.rb +35 -100
  25. data/spec/features/log_view_spec.rb +5 -5
  26. data/spec/features/rule_spec.rb +30 -30
  27. data/spec/features/user_view_spec.rb +0 -2
  28. data/spec/lib/logger_spec.rb +1 -1
  29. data/spec/models/api_auth_spec.rb +33 -12
  30. data/spec/models/event_spec.rb +1 -1
  31. data/spec/models/promise_spec.rb +1 -1
  32. data/spec/models/user_spec.rb +6 -6
  33. data/spec/spec_helper.rb +69 -9
  34. data/spec/support/{shared_connection_db_helpers.rb → clean_db_helpers.rb} +2 -2
  35. data/spec/support/delayed_job_helpers.rb +1 -1
  36. data/spec/support/{users.rb → integration_helpers.rb} +9 -11
  37. data/spec/support/{setup.rb → spec_setup.rb} +6 -19
  38. data/spec/support/user_helpers.rb +12 -0
  39. metadata +10 -21
  40. data/spec/dummy/app/assets/client/application.css +0 -13
  41. data/spec/dummy/app/assets/client/application.js +0 -15
  42. data/spec/support/chromedriver.rb +0 -41
  43. data/spec/support/components/netzke_combobox.rb +0 -57
  44. data/spec/support/components/netzke_grid.rb +0 -356
  45. data/spec/support/custom_matchers.rb +0 -18
  46. data/spec/support/custom_selectors.rb +0 -49
  47. data/spec/support/download_helper.rb +0 -52
  48. data/spec/support/helper.rb +0 -20
  49. data/spec/support/netzke.rb +0 -306
  50. data/spec/support/performance_helper.rb +0 -26
  51. data/spec/support/post_run_logger.rb +0 -32
  52. data/spec/support/shared_connection.rb +0 -31
  53. data/spec/support/structure_compare.rb +0 -62
  54. data/spec/support/suite.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a297a85d0d4cdfde6d667e399b64684900dba8e9b9faaffa355737c8c5c5678b
4
- data.tar.gz: 46c85fe0f1c7de9d3fba4d55b216d3e7daa24cc6a9f76cf1d75befb15cdf5284
3
+ metadata.gz: 8d6215dc0386a1fa52611c23d576350432d8dc8867f72dec1a7865717182e9e5
4
+ data.tar.gz: 66fe4f011556128fe04d5b897f653db57eb6032c4ef3f440ab363c105f0052ef
5
5
  SHA512:
6
- metadata.gz: ac982f3abebddb0f92269d41eed6c100c297feac1a9726693abaeba7b93b3d0c281525f2df3ed7d94d43e67a12a95eb2782f65d8010ab94e4e4157b43bb5bbf6
7
- data.tar.gz: f4816a56f8b3b61f72acb67faeffdd17f55010db418ab520f60f11c2058c123928c54e813c78e28c9b22a94b45620ea84568b091de90b41352735334da6658a7
6
+ metadata.gz: 8bde7326c5b29b7561371316e43207ded0b9d5b4246b5eb6948aa711eef74fc7e5fbed0fdf5758b61e7eb1549f0109ada0bcfed3910f86dc4e0cf4eeff128153
7
+ data.tar.gz: 4b2a99929bb2f8fcf4bd75a3b719c3c689dc3cd5e6e04726ea6e6fd07e900bcce821aaec76071d9befd33f604e9a3d4c3884bb0d0051a64669a5dd5c80ccfdd7
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- marty (2.3.15)
4
+ marty (2.4.0)
5
5
  aws-sigv4 (~> 1.0, >= 1.0.2)
6
6
  axlsx (= 3.0.0pre)
7
7
  coderay
@@ -106,7 +106,7 @@ GEM
106
106
  i18n (0.9.5)
107
107
  concurrent-ruby (~> 1.0)
108
108
  io-like (0.3.0)
109
- json-schema (2.8.1)
109
+ json-schema (2.8.0)
110
110
  addressable (>= 2.4)
111
111
  loofah (2.2.2)
112
112
  crass (~> 1.0.2)
@@ -7,14 +7,37 @@ class Marty::ApiAuthView < Marty::McflyGridPanel
7
7
  def configure(c)
8
8
  super
9
9
 
10
- c.title = I18n.t('api_auth', default: "API Authorization")
11
- c.model = "Marty::ApiAuth"
12
- c.attributes = [:app_name, :api_key, :script_name]
10
+ c.title = I18n.t('api_auth', default: "API Authorization")
11
+ c.editing = :in_form
12
+ c.pagination = :pagination
13
+ c.model = "Marty::ApiAuth"
14
+ c.attributes = [:aws, :entity_name, :api_key, :script_name]
13
15
  c.store_config.merge!({sorters: [{property: :app_name, direction: 'ASC'}]})
14
16
  end
15
17
 
16
- attribute :app_name do |c|
18
+ attribute :aws do |c|
19
+ c.width = 60
20
+ c.read_only = true
21
+ c.text = "AWS"
22
+ c.type = :boolean
23
+ c.getter = lambda do |r|
24
+ !!r.parameters['aws_api_key']
25
+ end
26
+ c.sorting_scope = get_json_sorter('parameters', 'aws_api_key')
27
+ c.filterable = true
28
+ c.filter_with = lambda do |rel, value, op|
29
+ rel.where("parameters->>'aws_api_key' IS #{value ? 'NOT' : ''} NULL")
30
+ end
31
+ end
32
+
33
+ attribute :entity_name do |c|
17
34
  c.flex = 1
35
+ c.text = "Entity Name"
36
+ c.getter = lambda do |r|
37
+ aws = !!r.parameters['aws_api_key']
38
+ entity = r.entity
39
+ entity ? entity.name : (aws ? nil : r.app_name)
40
+ end
18
41
  end
19
42
 
20
43
  attribute :api_key do |c|
@@ -12,6 +12,7 @@ class Marty::ApiConfigView < Marty::Grid
12
12
  :script,
13
13
  :node,
14
14
  :attr,
15
+ :api_class,
15
16
  :logged,
16
17
  :input_validated,
17
18
  :output_validated,
@@ -19,15 +20,33 @@ class Marty::ApiConfigView < Marty::Grid
19
20
  :created_at,
20
21
  :updated_at,
21
22
  ]
22
- c.paging = :pageination
23
+ c.paging = :pagination
23
24
  c.editing = :in_form
24
25
  c.store_config.merge!(
25
26
  sorters: [{ property: :script, direction: :ASC},
26
- { property: :node, direction: :ASC},
27
- { property: :attr, direction: :ASC},
27
+ { property: :node, direction: :ASC},
28
+ { property: :attr, direction: :ASC},
29
+ { property: :api_class, direction: :ASC},
28
30
  ])
29
31
  @model = c.model
30
32
  end
33
+
34
+ attribute :api_class do |c|
35
+ editor_config = {
36
+ trigger_action: :all,
37
+ xtype: :combo,
38
+ store: Marty::Api::Base.class_list,
39
+ forceSelection: true,
40
+ }
41
+ c.merge!(
42
+ column_config: { editor: editor_config },
43
+ field_config: editor_config,
44
+ type: :string,
45
+ )
46
+ c.width = 200
47
+ c.label = "API Class"
48
+ end
49
+
31
50
  attribute :script do |c|
32
51
  editor_config = {
33
52
  trigger_action: :all,
@@ -43,34 +62,38 @@ class Marty::ApiConfigView < Marty::Grid
43
62
  )
44
63
  c.width = 150
45
64
  end
65
+
46
66
  [:node, :attr].each do |a|
47
67
  attribute a do |c|
48
68
  c.width = 150
49
69
  c.setter = lambda { |r, v| r.send("#{a}=", v.blank? ? nil : v) }
50
70
  end
51
71
  end
72
+
52
73
  [:logged, :input_validated, :output_validated, :strict_validate].each do
53
74
  |a|
54
75
  attribute a do |c|
55
76
  c.width = 110
56
77
  end
57
78
  end
79
+
58
80
  [:created_at, :updated_at].each do |a|
59
81
  attribute a do |c|
60
82
  c.read_only = true
61
83
  end
62
84
  end
85
+
63
86
  def default_form_items
64
87
  [
65
88
  :script,
66
89
  :node,
67
90
  :attr,
91
+ :api_class,
68
92
  :logged,
69
93
  :input_validated,
70
94
  :output_validated,
71
95
  :strict_validate,
72
96
  ]
73
97
  end
74
-
75
98
  end
76
99
  ApiConfigView = Marty::ApiConfigView
@@ -73,8 +73,7 @@ module Layout
73
73
  ######################################################################
74
74
  # PG ENUM field handling
75
75
 
76
- def enum_column(c, class_or_array, col=nil)
77
- col ||= c.name.demodulize.tableize.singularize
76
+ def enum_column(c, class_or_array)
78
77
  vals = class_or_array.is_a?(Array) ? class_or_array : class_or_array::VALUES
79
78
  editor_config = {
80
79
  trigger_action: :all,
@@ -92,7 +91,6 @@ module Layout
92
91
  field_config: editor_config,
93
92
  type: :string,
94
93
  setter: enum_setter(c.name),
95
- sorting_scope: get_sorter(col)
96
94
  )
97
95
  end
98
96
 
@@ -114,10 +112,6 @@ module Layout
114
112
  lambda {|r, v| r.send("#{name}=", v.blank? || v == '---' ? nil : v)}
115
113
  end
116
114
 
117
- def get_sorter(col)
118
- lambda {|rel, dir| rel.order("#{col}::text #{dir.to_s}")}
119
- end
120
-
121
115
  ######################################################################
122
116
  # employ lots of hakery to implement NULLable boolean field in
123
117
  # Netzke 8.x.
@@ -203,4 +197,7 @@ module Layout
203
197
  c.align = 'right'
204
198
  end
205
199
 
200
+ def tooltip s1, s2
201
+ "<span data-qtip=\"#{s2}\">#{s1}</span>"
202
+ end
206
203
  end; end; end
@@ -1,3 +1,11 @@
1
1
  class Marty::Form < Netzke::Form::Base
2
2
  extend ::Marty::Permissions
3
+
4
+ client_class do |c|
5
+ c.find_component = l(<<-JS)
6
+ function(name) {
7
+ return Ext.ComponentQuery.query(`[name=${name}]`)[0];
8
+ }
9
+ JS
10
+ end
3
11
  end
@@ -13,6 +13,28 @@ class Marty::Grid < ::Netzke::Grid::Base
13
13
  end
14
14
 
15
15
  client_class do |c|
16
+ c.get_component = l(<<-JS)
17
+ function(name) {
18
+ return Ext.getCmp(name);
19
+ }
20
+ JS
21
+
22
+ c.find_component = l(<<-JS)
23
+ function(name) {
24
+ return Ext.ComponentQuery.query(`[name=${name}]`)[0];
25
+ }
26
+ JS
27
+
28
+ c.toggle_component_actions = l(<<-JS)
29
+ function(prefix, flag) {
30
+ for (var key in this.actions) {
31
+ if (key.substring(0, prefix.length) == prefix) {
32
+ this.actions[key].setDisabled(flag);
33
+ }
34
+ }
35
+ }
36
+ JS
37
+
16
38
  c.init_component = l(<<-JS)
17
39
  function() {
18
40
  this.dockedItems = this.dockedItems || [];
@@ -48,8 +70,7 @@ class Marty::Grid < ::Netzke::Grid::Base
48
70
  var me = this;
49
71
 
50
72
  var children = me.serverConfig.child_components || [];
51
- me.getSelectionModel().on(
52
- 'selectionchange',
73
+ me.onSelectionChange(
53
74
  function(m) {
54
75
  var has_sel = m.hasSelection();
55
76
 
@@ -66,18 +87,15 @@ class Marty::Grid < ::Netzke::Grid::Base
66
87
  }
67
88
 
68
89
  me.serverConfig.selected = rid;
69
-
70
- for (var key in me.actions) {
71
- // hacky -- assumes our functions start with "do"
72
- if (key.substring(0, 2) == "do") {
73
- me.actions[key].setDisabled(!has_sel);
74
- }
75
- }
90
+ me.toggleComponentActions('do', !has_sel);
76
91
 
77
92
  for (var child of children) {
78
- var comp = me.netzkeGetComponentFromParent(child);
93
+ var comp = me.getComponent(child)
79
94
  if (comp) {
80
95
  comp.serverConfig.parent_id = rid;
96
+ if (comp.toggleComponentActions) {
97
+ comp.toggleComponentActions('parent', !has_sel);
98
+ }
81
99
  if (comp.reload) { comp.reload() }
82
100
  }
83
101
  }
@@ -88,7 +106,7 @@ class Marty::Grid < ::Netzke::Grid::Base
88
106
  for (var event of ['update', 'netzkerefresh']) {
89
107
  store.on(event, function() {
90
108
  for (var link of linked) {
91
- var comp = me.netzkeGetComponentFromParent(link);
109
+ var comp = me.findComponent(link);
92
110
  if (comp && comp.reload) { comp.reload() }
93
111
  }
94
112
  }, this);
@@ -96,6 +114,15 @@ class Marty::Grid < ::Netzke::Grid::Base
96
114
  }
97
115
  JS
98
116
 
117
+ c.on_selection_change = l(<<-JS)
118
+ function(f) {
119
+ var me = this;
120
+ me.getSelectionModel().on('selectionchange', function(m) {
121
+ f(m);
122
+ });
123
+ }
124
+ JS
125
+
99
126
  c.do_view_in_form = l(<<-JS)
100
127
  function(record){
101
128
  this.netzkeLoadComponent("view_window", {
@@ -123,7 +150,7 @@ class Marty::Grid < ::Netzke::Grid::Base
123
150
  var children = me.serverConfig.child_components || [];
124
151
  this.store.reload();
125
152
  for (child of children) {
126
- var comp = me.netzkeGetComponentFromParent(child);
153
+ var comp = me.getComponent(child);
127
154
  if (comp && comp.reload) { comp.reload() }
128
155
  }
129
156
  }
@@ -134,13 +161,6 @@ class Marty::Grid < ::Netzke::Grid::Base
134
161
  this.filters.clearFilters();
135
162
  }
136
163
  JS
137
-
138
- c.netzkeGetComponentFromParent = l(<<-JS)
139
- function(component_path) {
140
- return this.netzkeGetParentComponent().netzkeGetComponent(component_path);
141
- }
142
- JS
143
-
144
164
  end
145
165
 
146
166
  ######################################################################
@@ -168,6 +188,12 @@ class Marty::Grid < ::Netzke::Grid::Base
168
188
  false
169
189
  end
170
190
 
191
+ action :clear_filters do |a|
192
+ a.text = "X"
193
+ a.tooltip = "Clear filters"
194
+ a.handler = :clear_filters
195
+ end
196
+
171
197
  def get_json_sorter(json_col, field)
172
198
  lambda do |r, dir|
173
199
  r.order("#{json_col} ->> '#{field}' " + dir.to_s)
@@ -58,7 +58,7 @@ class Marty::MainAuthApp < Marty::AuthApp
58
58
  [
59
59
  {
60
60
  text: 'API Management',
61
- icon_cls: "fa fa-wrench glyph",
61
+ icon_cls: "fa fa-fighter-jet glyph",
62
62
  disabled: !self.class.has_admin_perm?,
63
63
  menu: [
64
64
  :api_auth_view,
@@ -215,17 +215,19 @@ class Marty::MainAuthApp < Marty::AuthApp
215
215
  end
216
216
 
217
217
  action :api_config_view do |a|
218
- a.text = 'API Config Management'
219
- a.handler = :netzke_load_component_by_action
220
- a.icon_cls = "fa fa-cogs glyph"
221
- a.disabled = !self.class.has_admin_perm?
218
+ a.text = 'API Config Management'
219
+ a.tooltip = 'Manage API behavior and settings'
220
+ a.handler = :netzke_load_component_by_action
221
+ a.icon_cls = "fa fa-sliders-h glyph"
222
+ a.disabled = !self.class.has_admin_perm?
222
223
  end
223
224
 
224
225
  action :api_log_view do |a|
225
- a.text = 'API Log View'
226
- a.handler = :netzke_load_component_by_action
227
- a.icon_cls = "fa fa-cogs glyph"
228
- a.disabled = !self.class.has_admin_perm?
226
+ a.text = 'API Log View'
227
+ a.tooltip = 'View API logs'
228
+ a.handler = :netzke_load_component_by_action
229
+ a.icon_cls = "fa fa-pencil-alt glyph"
230
+ a.disabled = !self.class.has_admin_perm?
229
231
  end
230
232
 
231
233
  action :data_grid_view do |a|
@@ -285,7 +287,7 @@ class Marty::MainAuthApp < Marty::AuthApp
285
287
  a.disabled = !self.class.has_admin_perm?
286
288
  end
287
289
 
288
- ######################################################################
290
+ ######################################################################
289
291
 
290
292
  def bg_command(param)
291
293
  e, root, p = ENV['RAILS_ENV'], Rails.root, Marty::Config["RUBY_PATH"]
@@ -480,7 +482,6 @@ class Marty::MainAuthApp < Marty::AuthApp
480
482
  });
481
483
  }
482
484
  JS
483
-
484
485
  end
485
486
 
486
487
  action :select_posting do |a|
@@ -1,63 +1,53 @@
1
1
  class Marty::RpcController < ActionController::Base
2
2
  def evaluate
3
- res = do_eval(params["script"],
4
- params["tag"],
5
- params["node"],
6
- params["attrs"] || "[]",
7
- params["params"] || "{}",
8
- params["api_key"] || nil,
9
- params["background"],
10
- )
11
- respond_to do |format|
12
- format.json { send_data res.to_json }
13
- format.csv {
14
- # SEMI-HACKY: strip outer list if there's only one element.
15
- res = res[0] if res.is_a?(Array) && res.length==1
16
- send_data Marty::DataExporter.to_csv(res)
17
- }
18
- end
19
- end
3
+ massaged_params = massage_params(params)
4
+ api_config = Marty::ApiConfig.lookup(*massaged_params.values_at(
5
+ :script,
6
+ :node,
7
+ :attr)
8
+ ) || {}
20
9
 
21
- private
22
- # FIXME: move to (probably) agrim's schema code in lib
23
- def get_schema(tag, sname, node, attr)
24
- begin
25
- Marty::ScriptSet.new(tag).get_engine(sname+'Schemas').
26
- evaluate(node, attr, {})
27
- rescue => e
28
- use_message = e.message == 'No such script' ?
29
- 'Schema not defined' : 'Problem with schema: ' + e.message
30
- raise "Schema error for #{sname}/#{node} attrs=#{attr}: #{use_message}"
31
- end
32
- end
10
+ api = api_config.present? ? api_config[:api_class].constantize :
11
+ Marty::Api::Base
33
12
 
34
- def massage_message(msg)
35
- m = %r|'#/([^']+)' of type ([^ ]+) matched the disallowed schema|.match(msg)
36
- return msg unless m
37
- "disallowed parameter '#{m[1]}' of type #{m[2]} was received"
38
- end
13
+ api.respond_to(self) do
14
+ next massaged_params if massaged_params.include?(:error)
39
15
 
40
- def _get_errors(errs)
41
- if errs.is_a?(Array)
42
- errs.map { |err| _get_errors(err) }
43
- elsif errs.is_a?(Hash)
44
- if !errs.include?(:failed_attribute)
45
- errs.map { |k, v| _get_errors(v) }
46
- else
47
- fa, fragment, message, errors = errs.values_at(:failed_attribute,
48
- :fragment,
49
- :message, :errors)
50
- ((['AllOf','AnyOf','Not'].include?(fa) && fragment =='#/') ?
51
- [] : [massage_message(message)]) + _get_errors(errors || {})
52
- end
16
+ auth = api.is_authorized?(massaged_params)
17
+ next {error: "Permission denied"} unless auth
18
+
19
+ start_time = Time.zone.now
20
+
21
+ api_params = api.process_params(massaged_params)
22
+ api.before_evaluate(api_params)
23
+ result = api.evaluate(api_params.deep_dup, request, api_config.deep_dup)
24
+ api.after_evaluate(api_params.deep_dup, result)
25
+
26
+ log_params = {start_time: start_time, auth: auth}
27
+ api.log(result, api_params + log_params, request) if
28
+ api_config[:logged]
29
+
30
+ result
53
31
  end
54
32
  end
55
33
 
56
- def get_errors(errs)
57
- _get_errors(errs).flatten
58
- end
34
+ private
35
+
36
+ def massage_params request_params
37
+ sname,
38
+ tag,
39
+ node,
40
+ attr,
41
+ params,
42
+ api_key,
43
+ background = request_params.values_at(:script,
44
+ :tag,
45
+ :node,
46
+ :attrs,
47
+ :params,
48
+ :api_key,
49
+ :background)
59
50
 
60
- def do_eval(sname, tag, node, attr, params, api_key, background)
61
51
  # FIXME: small patch to allow for single attr array
62
52
  attr = ActiveSupport::JSON.decode(attr) rescue attr
63
53
 
@@ -66,116 +56,39 @@ class Marty::RpcController < ActionController::Base
66
56
 
67
57
  # if attr is a single attr array, remember to return as an array
68
58
  if attr.is_a? Array
69
- attr = attr[0]
59
+ attr = attr[0]
70
60
  ret_arr = true
71
61
  end
72
62
 
73
- start_time = Time.zone.now
74
63
  return {error: "Malformed attrs"} unless attr =~ /\A[a-z][a-zA-Z0-9_]*\z/
75
- return {error: "Bad params"} unless params.is_a?(String)
76
64
 
77
65
  begin
78
- params = ActiveSupport::JSON.decode(params)
79
- orig_params = params.clone
66
+ case params
67
+ when String
68
+ params = ActiveSupport::JSON.decode(params)
69
+ when ActionController::Parameters
70
+ params.permit!
71
+ params = JSON.parse(params.to_h.to_json)
72
+ when nil
73
+ params = {}
74
+ else
75
+ return {error: "Bad params"}
76
+ end
80
77
  rescue JSON::ParserError => e
81
78
  return {error: "Malformed params"}
82
79
  end
83
80
 
84
81
  return {error: "Malformed params"} unless params.is_a?(Hash)
85
- need_log,
86
- need_input_validate,
87
- need_output_validate,
88
- need_strict_validate = Marty::ApiConfig.lookup(sname, node, attr)
89
- opt = {validate_schema: true,
90
- errors_as_objects: true,
91
- version: Marty::JsonSchema::RAW_URI }
92
- to_append = {"\$schema" => Marty::JsonSchema::RAW_URI}
93
- validation_error = nil
94
-
95
- if need_input_validate
96
- begin
97
- schema = get_schema(tag, sname, node, attr)
98
- rescue => e
99
- return {error: e.message}
100
- end
101
- begin
102
- er = JSON::Validator.
103
- fully_validate(schema.merge(to_append), params, opt)
104
- rescue NameError
105
- return {error: "Unrecognized PgEnum for attribute #{attr}"}
106
- rescue => ex
107
- return {error: "#{attr}: #{ex.message}"}
108
- end
109
- validation_error = get_errors(er) if er.size > 0
110
- end
111
- return {error: "Error(s) validating: #{validation_error}"} if
112
- validation_error
113
-
114
- auth = Marty::ApiAuth.authorized?(sname, api_key)
115
- return {error: "Permission denied" } unless auth
116
82
 
117
- begin
118
- engine = Marty::ScriptSet.new(tag).get_engine(sname)
119
- rescue => e
120
- err_msg = "Can't get engine: #{sname || 'nil'} with tag: " +
121
- "#{tag || 'nil'}; message: #{e.message}"
122
- logger.info err_msg
123
- return {error: err_msg}
124
- end
125
-
126
- retval = nil
127
-
128
- begin
129
- if background
130
- result = engine.background_eval(node, params, attr)
131
- return retval = {"job_id" => result.__promise__.id}
132
- end
133
-
134
- res = engine.evaluate(node, attr, params)
135
-
136
- if need_output_validate && !(res.is_a?(Hash) && res['error'])
137
- begin
138
- schema = get_schema(tag, sname, node, attr + '_')
139
- rescue => e
140
- return {error: e.message}
141
- end
142
-
143
- begin
144
- er = JSON::Validator.fully_validate(schema.merge(to_append), res, opt)
145
- rescue NameError
146
- return {error: "Unrecognized PgEnum for attribute #{attr}"}
147
- rescue => ex
148
- return {error: "#{attr}: #{ex.message}"}
149
- end
150
-
151
- if er.size > 0
152
- errors = er.map{|e| e[:message]}
153
- Marty::Logger.error("API #{sname}:#{node}.#{attr}",
154
- {error: errors, data: res})
155
- res = need_strict_validate ? {error: "Error(s) validating: #{errors}",
156
- data: res} : res
157
- end
158
- end
159
- return retval = ret_arr ? [res] : res
160
- rescue => exc
161
- err_msg = Delorean::Engine.grok_runtime_exception(exc).symbolize_keys
162
- logger.info "Evaluation error: #{err_msg}"
163
- return retval = err_msg
164
- ensure
165
- error = Hash === retval ? retval[:error] : nil
166
- Marty::Log.write_log('api',
167
- "#{sname} - #{node}",
168
- {script: sname,
169
- node: node,
170
- attrs: (ret_arr ? [attr] : attr),
171
- input: orig_params,
172
- output: error ? nil : retval,
173
- start_time: start_time,
174
- end_time: Time.zone.now,
175
- error: error,
176
- remote_ip: request.remote_ip,
177
- auth_name: auth
178
- }) if need_log.present?
179
- end
83
+ {
84
+ script: sname,
85
+ tag: tag,
86
+ node: node,
87
+ attr: attr,
88
+ params: params,
89
+ api_key: api_key,
90
+ background: background,
91
+ return_array: ret_arr
92
+ }
180
93
  end
181
94
  end