openc3 5.14.0 → 5.14.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2b009f636dd8566127001ad9ee48972d584fb03baaf88389646048e7231dc54b
4
- data.tar.gz: 0ce2ff7aad089eba4794f4f15075bcf5e3087632f776eb76127c80af5256bda6
3
+ metadata.gz: 459b654a51a4d3b984681eb1b25165039e95d0a22c68e08973fc3539beee1b5c
4
+ data.tar.gz: cf6975c07ab38342228401d84a01f1ee672f4a74b7c2a697f2dc893aecfb4b3e
5
5
  SHA512:
6
- metadata.gz: 1d87b341b985cca628485419b0406b449289364497e4061024d0407551920fc8f62529fb35897761a1ae471c838cf2ce38d706fcf84eea4960abdd24a7608af5
7
- data.tar.gz: '0758dfda18babfc4c47f870efe074e5a6bbd371aee1ba2a362f3d851791f20c2f5955e7f144972198a461a314b0a2a334c02d8191c7387503c30a11d8bd53c50'
6
+ metadata.gz: 8368bda2e80639021df632271a972a5a716a8db380eb23dd4375d3334d10ca3001a5a33d9017caeeff684804338d4ba36a2adc180d1656f843d20440560d47ab
7
+ data.tar.gz: 195a9f6a3e4dbbadb1ed219765f627e1dd3cf96f9fd14a21e7891ea24e5cef6847eefb644ae8cfcbd15a894a32f0c23fc10bf405b9b2c3011553411f14f58b42
@@ -45,6 +45,7 @@ module OpenC3
45
45
  end
46
46
 
47
47
  def run
48
+ setup_microservice_topic()
48
49
  while true
49
50
  break if @cancel_thread
50
51
 
@@ -52,8 +53,9 @@ module OpenC3
52
53
  OpenC3.in_span("read_topics") do
53
54
  Topic.read_topics(@topics) do |topic, msg_id, msg_hash, redis|
54
55
  break if @cancel_thread
55
-
56
- if topic =~ /__DECOMINTERFACE/
56
+ if topic == @microservice_topic
57
+ microservice_cmd(topic, msg_id, msg_hash, redis)
58
+ elsif topic =~ /__DECOMINTERFACE/
57
59
  if msg_hash.key?('inject_tlm')
58
60
  handle_inject_tlm(msg_hash['inject_tlm'])
59
61
  next
@@ -62,12 +62,17 @@ module OpenC3
62
62
 
63
63
  def run
64
64
  setup_plws()
65
+ setup_microservice_topic()
65
66
  while true
66
67
  break if @cancel_thread
67
68
 
68
69
  Topic.read_topics(@topics) do |topic, msg_id, msg_hash, redis|
69
70
  break if @cancel_thread
70
- log_data(topic, msg_id, msg_hash, redis)
71
+ if topic == @microservice_topic
72
+ microservice_cmd(topic, msg_id, msg_hash, redis)
73
+ else
74
+ log_data(topic, msg_id, msg_hash, redis)
75
+ end
71
76
  @count += 1
72
77
  @metric.set(name: 'log_total', value: @count, type: 'counter')
73
78
  end
@@ -116,6 +116,7 @@ module OpenC3
116
116
  end
117
117
  @logger.info("Microservice initialized with config:\n#{@config}")
118
118
  @topics ||= []
119
+ @microservice_topic = "MICROSERVICE__#{@name}"
119
120
 
120
121
  # Get configuration for any targets
121
122
  @target_names = @config["target_names"]
@@ -210,5 +211,32 @@ module OpenC3
210
211
  @logger.info("Shutting down microservice complete: #{@name}")
211
212
  @shutdown_complete = true
212
213
  end
214
+
215
+ def setup_microservice_topic
216
+ @topics.append(@microservice_topic)
217
+ Thread.current[:topic_offsets] ||= {}
218
+ topic_offsets = Thread.current[:topic_offsets]
219
+ topic_offsets[@microservice_topic] = "0-0" # Always get all available
220
+ end
221
+
222
+ # Returns if the command was handled
223
+ def microservice_cmd(topic, msg_id, msg_hash, redis)
224
+ command = msg_hash['command']
225
+ case command
226
+ when 'ADD_TOPICS'
227
+ topics = JSON.parse(msg_hash['topics'])
228
+ if topics and Array === topics
229
+ topics.each do |new_topic|
230
+ @topics << new_topic unless @topics.include?(new_topic)
231
+ end
232
+ else
233
+ raise "Invalid topics given to microservice_cmd: #{topics}"
234
+ end
235
+ Topic.trim_topic(topic, msg_id)
236
+ return true
237
+ end
238
+ Topic.trim_topic(topic, msg_id)
239
+ return false
240
+ end
213
241
  end
214
242
  end
@@ -43,6 +43,7 @@ module OpenC3
43
43
  attr_accessor :secrets
44
44
  attr_accessor :prefix
45
45
  attr_accessor :disable_erb
46
+ attr_accessor :ignore_changes
46
47
 
47
48
  # NOTE: The following three class methods are used by the ModelController
48
49
  # and are reimplemented to enable various Model class methods to work
@@ -103,6 +104,7 @@ module OpenC3
103
104
  secrets: [],
104
105
  prefix: nil,
105
106
  disable_erb: nil,
107
+ ignore_changes: nil,
106
108
  scope:
107
109
  )
108
110
  parts = name.split("__")
@@ -128,6 +130,7 @@ module OpenC3
128
130
  @secrets = secrets
129
131
  @prefix = prefix
130
132
  @disable_erb = disable_erb
133
+ @ignore_changes = ignore_changes
131
134
  @bucket = Bucket.getClient()
132
135
  end
133
136
 
@@ -149,7 +152,8 @@ module OpenC3
149
152
  'needs_dependencies' => @needs_dependencies,
150
153
  'secrets' => @secrets.as_json(*a),
151
154
  'prefix' => @prefix,
152
- 'disable_erb' => @disable_erb
155
+ 'disable_erb' => @disable_erb,
156
+ 'ignore_changes' => @ignore_changes
153
157
  }
154
158
  end
155
159
 
@@ -342,7 +342,7 @@ module OpenC3
342
342
  raise message
343
343
  end
344
344
  rescue Exception => error
345
- Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: #{error}")
345
+ Logger.error("Error undeploying plugin model #{@name} in scope #{@scope} due to: #{error.formatted}")
346
346
  ensure
347
347
  # Double check everything is gone
348
348
  found = []
@@ -869,6 +869,42 @@ module OpenC3
869
869
  )
870
870
  end
871
871
  end
872
+
873
+ # Inform microservices of new topics
874
+ # Need to tell loggers to log, and decom to decom
875
+ # We do this for no downtime
876
+ raw_topics = []
877
+ decom_topics = []
878
+ packets.each do |packet|
879
+ if cmd_or_tlm == :TELEMETRY
880
+ raw_topics << "#{@scope}__TELEMETRY__{#{@name}}__#{packet.packet_name.upcase}"
881
+ decom_topics << "#{@scope}__DECOM__{#{@name}}__#{packet.packet_name.upcase}"
882
+ else
883
+ raw_topics << "#{@scope}__COMMAND__{#{@name}}__#{packet.packet_name.upcase}"
884
+ decom_topics << "#{@scope}__DECOMCMD__{#{@name}}__#{packet.packet_name.upcase}"
885
+ end
886
+ end
887
+ if cmd_or_tlm == :TELEMETRY
888
+ Topic.write_topic("MICROSERVICE__#{@scope}__PACKETLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
889
+ add_topics_to_microservice("#{@scope}__PACKETLOG__#{@name}", raw_topics)
890
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOMLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
891
+ add_topics_to_microservice("#{@scope}__DECOMLOG__#{@name}", decom_topics)
892
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOM__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
893
+ add_topics_to_microservice("#{@scope}__DECOM__#{@name}", raw_topics)
894
+ else
895
+ Topic.write_topic("MICROSERVICE__#{@scope}__COMMANDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => raw_topics.as_json.to_json})
896
+ add_topics_to_microservice("#{@scope}__COMMANDLOG__#{@name}", raw_topics)
897
+ Topic.write_topic("MICROSERVICE__#{@scope}__DECOMCMDLOG__#{@name}", {'command' => 'ADD_TOPICS', 'topics' => decom_topics.as_json.to_json})
898
+ add_topics_to_microservice("#{@scope}__DECOMCMDLOG__#{@name}", decom_topics)
899
+ end
900
+ end
901
+
902
+ def add_topics_to_microservice(microservice_name, topics)
903
+ model = MicroserviceModel.get_model(name: microservice_name, scope: @scope)
904
+ model.topics.concat(topics)
905
+ model.topics.uniq!
906
+ model.ignore_changes = true # Don't restart the microservice right now
907
+ model.update
872
908
  end
873
909
 
874
910
  def deploy_commmandlog_microservice(gem_path, variables, topics, instance = nil, parent = nil)
@@ -1109,7 +1145,6 @@ module OpenC3
1109
1145
  decom_command_topic_list = []
1110
1146
  packet_topic_list = []
1111
1147
  decom_topic_list = []
1112
- reduced_topic_list = []
1113
1148
  begin
1114
1149
  system.commands.packets(@name).each do |packet_name, packet|
1115
1150
  command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
@@ -1122,9 +1157,6 @@ module OpenC3
1122
1157
  system.telemetry.packets(@name).each do |packet_name, packet|
1123
1158
  packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
1124
1159
  decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
1125
- reduced_topic_list << "#{@scope}__REDUCED_MINUTE__{#{@name}}__#{packet_name}"
1126
- reduced_topic_list << "#{@scope}__REDUCED_HOUR__{#{@name}}__#{packet_name}"
1127
- reduced_topic_list << "#{@scope}__REDUCED_DAY__{#{@name}}__#{packet_name}"
1128
1160
  end
1129
1161
  rescue
1130
1162
  # No telemetry packets for this target
@@ -98,28 +98,30 @@ module OpenC3
98
98
  previous_parent = @previous_microservices[microservice_name]['parent']
99
99
  if @previous_microservices[microservice_name] != microservice_config
100
100
  # CHANGED
101
- scope = microservice_name.split("__")[0]
102
- Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
103
- if parent or previous_parent
104
- if parent == previous_parent
105
- # Same Parent - Respawn parent
106
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
107
- elsif parent and previous_parent
108
- # Parent changed - Respawn both parents
109
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
110
- @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
111
- elsif parent
112
- # Moved under a parent - Respawn parent and kill standalone
113
- @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
114
- @removed_microservices[microservice_name] = microservice_config
115
- else # previous_parent
116
- # Moved to standalone - Respawn previous parent and make new
117
- @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
118
- @new_microservices[microservice_name] = microservice_config
101
+ if not microservice_config['ignore_changes']
102
+ scope = microservice_name.split("__")[0]
103
+ Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
104
+ if parent or previous_parent
105
+ if parent == previous_parent
106
+ # Same Parent - Respawn parent
107
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
108
+ elsif parent and previous_parent
109
+ # Parent changed - Respawn both parents
110
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
111
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
112
+ elsif parent
113
+ # Moved under a parent - Respawn parent and kill standalone
114
+ @changed_microservices[parent] = @microservices[parent] if @microservices[parent] and @previous_microservices[parent]
115
+ @removed_microservices[microservice_name] = microservice_config
116
+ else # previous_parent
117
+ # Moved to standalone - Respawn previous parent and make new
118
+ @changed_microservices[previous_parent] = @microservices[previous_parent] if @microservices[previous_parent] and @previous_microservices[previous_parent]
119
+ @new_microservices[microservice_name] = microservice_config
120
+ end
121
+ else
122
+ # Respawn regular microservice
123
+ @changed_microservices[microservice_name] = microservice_config
119
124
  end
120
- else
121
- # Respawn regular microservice
122
- @changed_microservices[microservice_name] = microservice_config
123
125
  end
124
126
  end
125
127
  else
@@ -303,6 +303,10 @@ module OpenC3
303
303
  @config.commands
304
304
  end
305
305
 
306
+ def dynamic_add_packet(packet, affect_ids: false)
307
+ @config.dynamic_add_packet(packet, :COMMAND, affect_ids: affect_ids)
308
+ end
309
+
306
310
  protected
307
311
 
308
312
  def set_parameters(command, params, range_checking)
@@ -315,30 +315,60 @@ module OpenC3
315
315
  hash = @cmd_id_value_hash[@current_packet.target_name]
316
316
  hash = {} unless hash
317
317
  @cmd_id_value_hash[@current_packet.target_name] = hash
318
- update_id_value_hash(hash)
318
+ update_id_value_hash(@current_packet, hash)
319
319
  else
320
320
  @telemetry[@current_packet.target_name][@current_packet.packet_name] = @current_packet
321
321
  hash = @tlm_id_value_hash[@current_packet.target_name]
322
322
  hash = {} unless hash
323
323
  @tlm_id_value_hash[@current_packet.target_name] = hash
324
- update_id_value_hash(hash)
324
+ update_id_value_hash(@current_packet, hash)
325
325
  end
326
326
  @current_packet = nil
327
327
  @current_item = nil
328
328
  end
329
329
  end
330
330
 
331
+ def dynamic_add_packet(packet, cmd_or_tlm = :TELEMETRY, affect_ids: false)
332
+ if cmd_or_tlm == :COMMAND
333
+ @commands[packet.target_name][packet.packet_name] = packet
334
+
335
+ if affect_ids
336
+ hash = @cmd_id_value_hash[packet.target_name]
337
+ hash = {} unless hash
338
+ @cmd_id_value_hash[packet.target_name] = hash
339
+ update_id_value_hash(packet, hash)
340
+ end
341
+ else
342
+ @telemetry[packet.target_name][packet.packet_name] = packet
343
+
344
+ # Update latest_data lookup for telemetry
345
+ packet.sorted_items.each do |item|
346
+ target_latest_data = @latest_data[packet.target_name]
347
+ target_latest_data[item.name] ||= []
348
+ latest_data_packets = target_latest_data[item.name]
349
+ latest_data_packets << packet unless latest_data_packets.include?(packet)
350
+ end
351
+
352
+ if affect_ids
353
+ hash = @tlm_id_value_hash[packet.target_name]
354
+ hash = {} unless hash
355
+ @tlm_id_value_hash[packet.target_name] = hash
356
+ update_id_value_hash(packet, hash)
357
+ end
358
+ end
359
+ end
360
+
331
361
  protected
332
362
 
333
- def update_id_value_hash(hash)
334
- if @current_packet.id_items.length > 0
363
+ def update_id_value_hash(packet, hash)
364
+ if packet.id_items.length > 0
335
365
  key = []
336
- @current_packet.id_items.each do |item|
366
+ packet.id_items.each do |item|
337
367
  key << item.id_value
338
368
  end
339
- hash[key] = @current_packet
369
+ hash[key] = packet
340
370
  else
341
- hash['CATCHALL'.freeze] = @current_packet
371
+ hash['CATCHALL'.freeze] = packet
342
372
  end
343
373
  end
344
374
 
@@ -442,5 +442,9 @@ module OpenC3
442
442
  def all
443
443
  @config.telemetry
444
444
  end
445
+
446
+ def dynamic_add_packet(packet, affect_ids: false)
447
+ @config.dynamic_add_packet(packet, :TELEMETRY, affect_ids: affect_ids)
448
+ end
445
449
  end # class Telemetry
446
450
  end
@@ -60,6 +60,9 @@ module OpenC3
60
60
  # The current limits set
61
61
  @@limits_set = nil
62
62
 
63
+ # Callbacks to call once @@instance is created
64
+ @@post_instance_callbacks = []
65
+
63
66
  # @return [Symbol] The current limits_set of the system returned from Redis
64
67
  def self.limits_set
65
68
  unless @@limits_set
@@ -72,6 +75,14 @@ module OpenC3
72
75
  @@limits_set = value.to_s.intern
73
76
  end
74
77
 
78
+ def self.add_post_instance_callback(callback)
79
+ if @@instance
80
+ callback.call()
81
+ else
82
+ @@post_instance_callbacks << callback
83
+ end
84
+ end
85
+
75
86
  def self.setup_targets(target_names, base_dir, scope:)
76
87
  # Nothing to do if there are no targets
77
88
  return if target_names.nil? or target_names.length == 0
@@ -121,11 +132,30 @@ module OpenC3
121
132
  raise "System.instance parameters are required on first call" unless target_names and target_config_dir
122
133
 
123
134
  @@instance_mutex.synchronize do
135
+ return @@instance if @@instance
124
136
  @@instance ||= self.new(target_names, target_config_dir)
137
+ @@post_instance_callbacks.each do |callback|
138
+ callback.call
139
+ end
125
140
  return @@instance
126
141
  end
127
142
  end
128
143
 
144
+ # Dynamically add packets to the system instance
145
+ #
146
+ # @param dynamic_packets [Array of packets]
147
+ # @param cmd_or_tlm [Symbol] :COMMAND or :TELEMETRY
148
+ # @param affect_ids [Boolean] Whether to affect packet id lookup or not
149
+ def self.dynamic_update(dynamic_packets, cmd_or_tlm = :TELEMETRY, affect_ids: false)
150
+ dynamic_packets.each do |packet|
151
+ if cmd_or_tlm == :TELEMETRY
152
+ @@instance.telemetry.dynamic_add_packet(packet, affect_ids: affect_ids)
153
+ else
154
+ @@instance.commands.dynamic_add_packet(packet, affect_ids: affect_ids)
155
+ end
156
+ end
157
+ end
158
+
129
159
  # Create a new System object.
130
160
  #
131
161
  # @param target_names [Array of target names]
@@ -1,14 +1,14 @@
1
1
  # encoding: ascii-8bit
2
2
 
3
- OPENC3_VERSION = '5.14.0'
3
+ OPENC3_VERSION = '5.14.1'
4
4
  module OpenC3
5
5
  module Version
6
6
  MAJOR = '5'
7
7
  MINOR = '14'
8
- PATCH = '0'
8
+ PATCH = '1'
9
9
  OTHER = ''
10
- BUILD = 'dd31e4853fa50ed08ee3100e43e75849617d0a47'
10
+ BUILD = '902e54e502f6070c58183746a7db21a50e7b5263'
11
11
  end
12
- VERSION = '5.14.0'
13
- GEM_VERSION = '5.14.0'
12
+ VERSION = '5.14.1'
13
+ GEM_VERSION = '5.14.1'
14
14
  end
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "scripts": {
5
5
  "ng": "ng",
6
6
  "start": "ng serve",
@@ -12,7 +12,7 @@
12
12
  },
13
13
  "private": true,
14
14
  "dependencies": {
15
- "@openc3/tool-common": "5.14.0",
15
+ "@openc3/tool-common": "5.14.1",
16
16
  "@angular/animations": "^17.0.8",
17
17
  "@angular/cdk": "^17.0.4",
18
18
  "@angular/common": "^17.0.8",
@@ -11,7 +11,7 @@
11
11
  "smui-theme": "smui-theme compile build/smui.css -i src/theme"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.0",
14
+ "@openc3/tool-common": "5.14.1",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "@smui/button": "^7.0.0-beta.16",
17
17
  "@smui/card": "^7.0.0-beta.16",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "<%= tool_name %>",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "serve": "vue-cli-service serve",
@@ -11,7 +11,7 @@
11
11
  "test:components": "vue-cli-service test:components"
12
12
  },
13
13
  "dependencies": {
14
- "@openc3/tool-common": "5.14.0",
14
+ "@openc3/tool-common": "5.14.1",
15
15
  "@astrouxds/astro-web-components": "7.20.0",
16
16
  "axios": "1.6.5",
17
17
  "date-fns": "2.30.0",
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "widget",
3
- "version": "5.14.0",
3
+ "version": "5.14.1",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "build": "vue-cli-service build --target lib --dest tools/widgets/<%= widget_name %> --formats umd-min <%= widget_path %> --name <%= widget_name %>"
7
7
  },
8
8
  "dependencies": {
9
- "@openc3/tool-common": "5.14.0",
9
+ "@openc3/tool-common": "5.14.1",
10
10
  "@astrouxds/astro-web-components": "7.20.0",
11
11
  "vue": "2.7.16",
12
12
  "vuetify": "2.7.1"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openc3
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.14.0
4
+ version: 5.14.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Melton
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2024-01-18 00:00:00.000000000 Z
12
+ date: 2024-01-24 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler