Class: OpenC3::ReactionModel
- Inherits:
-
Model
show all
- Defined in:
- lib/openc3/models/reaction_model.rb
Constant Summary
collapse
- PRIMARY_KEY =
'__openc3__reaction'.freeze
- SCRIPT_REACTION =
'script'.freeze
- COMMAND_REACTION =
'command'.freeze
- NOTIFY_REACTION =
'notify'.freeze
- ACTION_TYPES =
[SCRIPT_REACTION, COMMAND_REACTION, NOTIFY_REACTION]
Instance Attribute Summary collapse
Attributes inherited from Model
#plugin, #updated_at
Class Method Summary
collapse
Instance Method Summary
collapse
-
#as_json(*a) ⇒ Hash
Generated from the ReactionModel.
-
#awaken ⇒ Object
-
#create ⇒ Object
-
#create_microservice(topics:) ⇒ Object
-
#deploy ⇒ Object
-
#initialize(name:, scope:, snooze:, actions:, triggers:, trigger_level:, enabled: true, snoozed_until: nil, username: nil, shard: 0, updated_at: nil) ⇒ ReactionModel
constructor
A new instance of ReactionModel.
-
#notify(kind:) ⇒ Object
-
update the redis stream / reaction topic that something has changed.
-
#notify_disable ⇒ Object
-
#notify_enable ⇒ Object
-
#notify_execute ⇒ Object
-
#sleep ⇒ Object
-
#undeploy ⇒ Object
-
#update ⇒ Object
-
#validate_actions(actions) ⇒ Object
-
#validate_level(level) ⇒ Object
-
#validate_snooze(snooze) ⇒ Object
-
#validate_triggers(triggers) ⇒ Object
-
#verify_triggers ⇒ Object
Methods inherited from Model
#check_disable_erb, #destroy, #destroyed?, filter, find_all_by_plugin, get_all_models, get_model, handle_config, set, store, store_queued
Constructor Details
#initialize(name:, scope:, snooze:, actions:, triggers:, trigger_level:, enabled: true, snoozed_until: nil, username: nil, shard: 0, updated_at: nil) ⇒ ReactionModel
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
# File 'lib/openc3/models/reaction_model.rb', line 87
def initialize(
name:,
scope:,
snooze:,
actions:,
triggers:,
trigger_level:,
enabled: true,
snoozed_until: nil,
username: nil,
shard: 0,
updated_at: nil
)
super("#{scope}#{PRIMARY_KEY}", name: name, scope: scope)
@microservice_name = "#{scope}__OPENC3__REACTION"
@enabled = enabled
@snoozed_until = snoozed_until
@trigger_level = validate_level(trigger_level)
@snooze = validate_snooze(snooze)
@actions = validate_actions(actions)
@triggers = validate_triggers(triggers)
@username = username
@shard = shard.to_i
@updated_at = updated_at
end
|
Instance Attribute Details
Returns the value of attribute actions.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def actions
@actions
end
|
Returns the value of attribute enabled.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def enabled
@enabled
end
|
Returns the value of attribute name.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def name
@name
end
|
Returns the value of attribute scope.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def scope
@scope
end
|
Returns the value of attribute shard.
85
86
87
|
# File 'lib/openc3/models/reaction_model.rb', line 85
def shard
@shard
end
|
Returns the value of attribute snooze.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def snooze
@snooze
end
|
#snoozed_until ⇒ Object
Returns the value of attribute snoozed_until.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def snoozed_until
@snoozed_until
end
|
#trigger_level ⇒ Object
Returns the value of attribute trigger_level.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def trigger_level
@trigger_level
end
|
Returns the value of attribute triggers.
84
85
86
|
# File 'lib/openc3/models/reaction_model.rb', line 84
def triggers
@triggers
end
|
Returns the value of attribute username.
85
86
87
|
# File 'lib/openc3/models/reaction_model.rb', line 85
def username
@username
end
|
Class Method Details
57
58
59
|
# File 'lib/openc3/models/reaction_model.rb', line 57
def self.all(scope:)
super("#{scope}#{PRIMARY_KEY}")
end
|
.create_unique_name(scope:) ⇒ Object
39
40
41
42
43
44
45
46
|
# File 'lib/openc3/models/reaction_model.rb', line 39
def self.create_unique_name(scope:)
reaction_names = self.names(scope: scope)
num = 1
if reaction_names[-1]
num = reaction_names[-1][5..-1].to_i + 1
end
return "REACT#{num}"
end
|
.delete(name:, scope:) ⇒ Object
Check dependents before delete.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/openc3/models/reaction_model.rb', line 67
def self.delete(name:, scope:)
model = self.get(name: name, scope: scope)
if model.nil?
raise ReactionInputError.new "reaction '#{name}' does not exist"
end
model.triggers.each do | trigger |
trigger_model = TriggerModel.get(name: trigger['name'], group: trigger['group'], scope: scope)
trigger_model.update_dependents(dependent: name, remove: true)
trigger_model.update()
end
Store.hdel("#{scope}#{PRIMARY_KEY}", name)
model.undeploy()
end
|
.from_json(json, name:, scope:) ⇒ ReactionModel
274
275
276
277
278
|
# File 'lib/openc3/models/reaction_model.rb', line 274
def self.from_json(json, name:, scope:)
json = JSON.parse(json, :allow_nan => true, :create_additions => true) if String === json
raise "json data is nil" if json.nil?
self.new(**json.transform_keys(&:to_sym), name: name, scope: scope)
end
|
49
50
51
52
53
54
|
# File 'lib/openc3/models/reaction_model.rb', line 49
def self.get(name:, scope:)
json = super("#{scope}#{PRIMARY_KEY}", name: name)
unless json.nil?
self.from_json(json, name: name, scope: scope)
end
end
|
62
63
64
|
# File 'lib/openc3/models/reaction_model.rb', line 62
def self.names(scope:)
super("#{scope}#{PRIMARY_KEY}")
end
|
Instance Method Details
#as_json(*a) ⇒ Hash
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
# File 'lib/openc3/models/reaction_model.rb', line 257
def as_json(*a)
return {
'name' => @name,
'scope' => @scope,
'enabled' => @enabled,
'trigger_level' => @trigger_level,
'snooze' => @snooze,
'snoozed_until' => @snoozed_until,
'triggers' => @triggers,
'actions' => @actions,
'username' => @username,
'shard' => @shard,
'updated_at' => @updated_at
}
end
|
249
250
251
252
253
254
|
# File 'lib/openc3/models/reaction_model.rb', line 249
def awaken
@snoozed_until = nil
@updated_at = Time.now.to_nsec_from_epoch
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
notify(kind: 'awakened')
end
|
203
204
205
206
207
208
209
210
211
|
# File 'lib/openc3/models/reaction_model.rb', line 203
def create
unless Store.hget(@primary_key, @name).nil?
raise ReactionInputError.new "existing reaction found: #{@name}"
end
verify_triggers()
@updated_at = Time.now.to_nsec_from_epoch
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
notify(kind: 'created')
end
|
#create_microservice(topics:) ⇒ Object
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
# File 'lib/openc3/models/reaction_model.rb', line 290
def create_microservice(topics:)
microservice = MicroserviceModel.new(
name: @microservice_name,
folder_name: nil,
cmd: ['ruby', 'reaction_microservice.rb', @microservice_name],
work_dir: '/openc3-enterprise/lib/openc3-enterprise/microservices',
options: [],
topics: topics,
target_names: [],
plugin: nil,
shard: @shard,
scope: @scope
)
microservice.create
end
|
307
308
309
310
311
312
|
# File 'lib/openc3/models/reaction_model.rb', line 307
def deploy
topics = ["#{@scope}__openc3_autonomic"]
if MicroserviceModel.get_model(name: @microservice_name, scope: @scope).nil?
create_microservice(topics: topics)
end
end
|
#notify(kind:) ⇒ Object
281
282
283
284
285
286
287
288
|
# File 'lib/openc3/models/reaction_model.rb', line 281
def notify(kind:)
notification = {
'kind' => kind,
'type' => 'reaction',
'data' => JSON.generate(as_json(:allow_nan => true)),
}
AutonomicTopic.write_notification(notification, scope: @scope)
end
|
#notify_disable ⇒ Object
226
227
228
229
230
231
232
|
# File 'lib/openc3/models/reaction_model.rb', line 226
def notify_disable
@enabled = false
@snoozed_until = nil
notify(kind: 'disabled')
end
|
#notify_enable ⇒ Object
220
221
222
223
224
|
# File 'lib/openc3/models/reaction_model.rb', line 220
def notify_enable
@enabled = true
notify(kind: 'enabled')
end
|
#notify_execute ⇒ Object
234
235
236
237
238
|
# File 'lib/openc3/models/reaction_model.rb', line 234
def notify_execute
@updated_at = Time.now.to_nsec_from_epoch
notify(kind: 'executed')
end
|
240
241
242
243
244
245
246
247
|
# File 'lib/openc3/models/reaction_model.rb', line 240
def sleep
if @snooze > 0
@snoozed_until = Time.now.to_i + @snooze
@updated_at = Time.now.to_nsec_from_epoch
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
notify(kind: 'snoozed')
end
end
|
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
|
# File 'lib/openc3/models/reaction_model.rb', line 314
def undeploy
return unless ReactionModel.names(scope: @scope).empty?
model = MicroserviceModel.get_model(name: @microservice_name, scope: @scope)
if model
notification = {
'kind' => 'undeployed',
'type' => 'reaction',
'data' => JSON.generate({
'name' => @microservice_name,
'updated_at' => Time.now.to_nsec_from_epoch,
}),
}
AutonomicTopic.write_notification(notification, scope: @scope)
model.destroy
end
end
|
213
214
215
216
217
218
|
# File 'lib/openc3/models/reaction_model.rb', line 213
def update
verify_triggers()
@updated_at = Time.now.to_nsec_from_epoch
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
end
|
#validate_actions(actions) ⇒ Object
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
|
# File 'lib/openc3/models/reaction_model.rb', line 164
def validate_actions(actions)
unless actions.is_a?(Array)
raise ReactionInputError.new "invalid actions, must be array of hashes: #{actions}"
end
actions.each do | action |
unless action.is_a?(Hash)
raise ReactionInputError.new "invalid action, must be a hash: #{action}"
end
action_type = action['type']
if action_type.nil?
raise ReactionInputError.new "invalid action, must contain 'type': #{action}"
elsif action['value'].nil?
raise ReactionInputError.new "invalid action, must contain 'value': #{action}"
end
unless ACTION_TYPES.include?(action_type)
raise ReactionInputError.new "invalid action type '#{action_type}', must be one of #{ACTION_TYPES}"
end
end
return actions
end
|
#validate_level(level) ⇒ Object
127
128
129
130
131
132
133
134
|
# File 'lib/openc3/models/reaction_model.rb', line 127
def validate_level(level)
case level
when 'EDGE', 'LEVEL'
return level
else
raise ReactionInputError.new "invalid trigger level, must be EDGE or LEVEL: #{level}"
end
end
|
#validate_snooze(snooze) ⇒ Object
136
137
138
139
140
|
# File 'lib/openc3/models/reaction_model.rb', line 136
def validate_snooze(snooze)
Integer(snooze)
rescue
raise ReactionInputError.new "invalid snooze value: #{snooze}"
end
|
#validate_triggers(triggers) ⇒ Object
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
# File 'lib/openc3/models/reaction_model.rb', line 142
def validate_triggers(triggers)
unless triggers.is_a?(Array)
raise ReactionInputError.new "invalid triggers, must be array of hashes: #{triggers}"
end
trigger_hash = Hash.new()
triggers.each do | trigger |
unless trigger.is_a?(Hash)
raise ReactionInputError.new "invalid trigger, must be hash: #{trigger}"
end
if trigger['name'].nil? || trigger['group'].nil?
raise ReactionInputError.new "invalid trigger, must contain 'name' and 'group' keys: #{trigger}"
end
trigger_name = trigger['name']
unless trigger_hash[trigger_name].nil?
raise ReactionInputError.new "no duplicate triggers allowed: #{triggers}"
else
trigger_hash[trigger_name] = 1
end
end
return triggers
end
|
#verify_triggers ⇒ Object
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
|
# File 'lib/openc3/models/reaction_model.rb', line 185
def verify_triggers
trigger_models = []
@triggers.each do | trigger |
model = TriggerModel.get(name: trigger['name'], group: trigger['group'], scope: @scope)
if model.nil?
raise ReactionInputError.new "failed to find trigger: #{trigger}"
end
trigger_models << model
end
if trigger_models.empty?
raise ReactionInputError.new "reaction must contain at least one valid trigger: #{@triggers}"
end
trigger_models.each do | trigger_model |
trigger_model.update_dependents(dependent: @name)
trigger_model.update()
end
end
|