openc3 5.1.1 → 5.2.0

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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/bin/openc3cli +48 -9
  3. data/data/config/interface_modifiers.yaml +14 -0
  4. data/data/config/parameter_modifiers.yaml +5 -3
  5. data/data/config/screen.yaml +12 -8
  6. data/data/config/target.yaml +33 -0
  7. data/ext/openc3/ext/config_parser/config_parser.c +66 -63
  8. data/ext/openc3/ext/packet/packet.c +1 -4
  9. data/lib/openc3/api/README.md +5 -0
  10. data/lib/openc3/api/api.rb +3 -1
  11. data/lib/openc3/api/cmd_api.rb +43 -112
  12. data/lib/openc3/api/interface_api.rb +3 -3
  13. data/lib/openc3/api/offline_access_api.rb +78 -0
  14. data/lib/openc3/api/settings_api.rb +3 -1
  15. data/lib/openc3/api/stash_api.rb +63 -0
  16. data/lib/openc3/api/target_api.rb +4 -5
  17. data/lib/openc3/config/config_parser.rb +47 -47
  18. data/lib/openc3/interfaces/interface.rb +11 -1
  19. data/lib/openc3/interfaces/protocols/burst_protocol.rb +30 -16
  20. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +8 -2
  21. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +2 -2
  22. data/lib/openc3/interfaces/protocols/override_protocol.rb +2 -2
  23. data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -1
  24. data/lib/openc3/io/json_api_object.rb +30 -9
  25. data/lib/openc3/io/json_drb.rb +6 -1
  26. data/lib/openc3/io/json_drb_object.rb +18 -9
  27. data/lib/openc3/io/json_rpc.rb +5 -3
  28. data/lib/openc3/logs/buffered_packet_log_writer.rb +1 -1
  29. data/lib/openc3/logs/log_writer.rb +8 -2
  30. data/lib/openc3/microservices/cleanup_microservice.rb +3 -3
  31. data/lib/openc3/microservices/decom_microservice.rb +8 -8
  32. data/lib/openc3/microservices/interface_microservice.rb +86 -71
  33. data/lib/openc3/microservices/log_microservice.rb +5 -3
  34. data/lib/openc3/microservices/microservice.rb +18 -14
  35. data/lib/openc3/microservices/multi_microservice.rb +62 -0
  36. data/lib/openc3/microservices/periodic_microservice.rb +58 -0
  37. data/lib/openc3/microservices/reaction_microservice.rb +61 -47
  38. data/lib/openc3/microservices/reducer_microservice.rb +64 -40
  39. data/lib/openc3/microservices/router_microservice.rb +4 -4
  40. data/lib/openc3/microservices/text_log_microservice.rb +2 -2
  41. data/lib/openc3/microservices/timeline_microservice.rb +44 -30
  42. data/lib/openc3/microservices/trigger_group_microservice.rb +39 -36
  43. data/lib/openc3/migrations/20221202214600_add_target_names.rb +30 -0
  44. data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +65 -0
  45. data/lib/openc3/models/cvt_model.rb +1 -1
  46. data/lib/openc3/models/gem_model.rb +24 -20
  47. data/lib/openc3/models/interface_model.rb +69 -35
  48. data/lib/openc3/models/metadata_model.rb +1 -1
  49. data/lib/openc3/models/microservice_model.rb +7 -24
  50. data/lib/openc3/models/migration_model.rb +52 -0
  51. data/lib/openc3/models/model.rb +2 -7
  52. data/lib/openc3/models/note_model.rb +1 -1
  53. data/lib/openc3/models/offline_access_model.rb +55 -0
  54. data/lib/openc3/models/plugin_model.rb +12 -3
  55. data/lib/openc3/models/reaction_model.rb +6 -2
  56. data/lib/openc3/models/scope_model.rb +89 -13
  57. data/lib/openc3/models/settings_model.rb +1 -1
  58. data/lib/openc3/models/stash_model.rb +53 -0
  59. data/lib/openc3/models/target_model.rb +301 -130
  60. data/lib/openc3/models/tool_model.rb +1 -12
  61. data/lib/openc3/models/widget_model.rb +1 -6
  62. data/lib/openc3/operators/microservice_operator.rb +45 -6
  63. data/lib/openc3/operators/operator.rb +27 -5
  64. data/lib/openc3/packets/commands.rb +1 -25
  65. data/lib/openc3/packets/limits.rb +0 -75
  66. data/lib/openc3/packets/packet.rb +0 -28
  67. data/lib/openc3/packets/packet_item.rb +23 -0
  68. data/lib/openc3/packets/packet_item_limits.rb +2 -2
  69. data/lib/openc3/packets/parsers/state_parser.rb +10 -6
  70. data/lib/openc3/packets/telemetry.rb +1 -45
  71. data/lib/openc3/script/commands.rb +41 -71
  72. data/lib/openc3/script/extract.rb +15 -1
  73. data/lib/openc3/script/{calendar.rb → metadata.rb} +42 -17
  74. data/lib/openc3/script/script.rb +13 -5
  75. data/lib/openc3/script/storage.rb +3 -1
  76. data/lib/openc3/system/system.rb +19 -17
  77. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +4 -4
  78. data/lib/openc3/top_level.rb +3 -3
  79. data/lib/openc3/topics/command_decom_topic.rb +2 -2
  80. data/lib/openc3/topics/command_topic.rb +7 -6
  81. data/lib/openc3/topics/interface_topic.rb +2 -2
  82. data/lib/openc3/topics/router_topic.rb +1 -1
  83. data/lib/openc3/topics/telemetry_topic.rb +2 -1
  84. data/lib/openc3/utilities/authentication.rb +35 -14
  85. data/lib/openc3/utilities/aws_bucket.rb +4 -3
  86. data/lib/openc3/utilities/bucket.rb +4 -2
  87. data/lib/openc3/utilities/bucket_file_cache.rb +3 -8
  88. data/lib/openc3/utilities/bucket_utilities.rb +77 -15
  89. data/lib/openc3/utilities/local_mode.rb +12 -9
  90. data/lib/openc3/utilities/logger.rb +17 -9
  91. data/lib/openc3/utilities/message_log.rb +6 -5
  92. data/lib/openc3/utilities/migration.rb +22 -0
  93. data/lib/openc3/utilities/store_autoload.rb +7 -5
  94. data/lib/openc3/utilities/target_file.rb +9 -7
  95. data/lib/openc3/version.rb +6 -6
  96. data/lib/openc3.rb +2 -1
  97. metadata +14 -3
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/config/config_parser'
@@ -77,7 +77,13 @@ module OpenC3
77
77
  packet_data = nil
78
78
  identified_packet = nil
79
79
 
80
- @interface.target_names.each do |target_name|
80
+ if @telemetry
81
+ target_names = @interface.tlm_target_names
82
+ else
83
+ target_names = @interface.cmd_target_names
84
+ end
85
+
86
+ target_names.each do |target_name|
81
87
  target_packets = nil
82
88
  unique_id_mode = false
83
89
  begin
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/config/config_parser'
@@ -40,7 +40,7 @@ module OpenC3
40
40
  def read_packet(packet)
41
41
  # Need to make sure packet is identified and defined
42
42
  target_names = nil
43
- target_names = @interface.target_names if @interface
43
+ target_names = @interface.tlm_target_names if @interface
44
44
  identified_packet = System.telemetry.identify_and_define_packet(packet, target_names)
45
45
  if identified_packet
46
46
  if identified_packet.target_name == @target_name && identified_packet.packet_name == @packet_name
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/interfaces/protocols/protocol'
@@ -41,7 +41,7 @@ module OpenC3
41
41
  if @interface.override_tlm && !@interface.override_tlm.empty?
42
42
  # Need to make sure packet is identified and defined
43
43
  target_names = nil
44
- target_names = @interface.target_names if @interface
44
+ target_names = @interface.tlm_target_names if @interface
45
45
  identified_packet = System.telemetry.identify_and_define_packet(packet, target_names)
46
46
  if identified_packet
47
47
  packet = identified_packet
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'socket'
@@ -398,6 +398,8 @@ module OpenC3
398
398
 
399
399
  interface = StreamInterface.new
400
400
  interface.target_names = @target_names
401
+ interface.cmd_target_names = @cmd_target_names
402
+ interface.tlm_target_names = @tlm_target_names
401
403
  if @raw_logger_pair
402
404
  interface.raw_logger_pair = @raw_logger_pair.clone
403
405
  interface.raw_logger_pair.start if @raw_logging_enabled
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3'
@@ -48,7 +48,7 @@ module OpenC3
48
48
  # server = JsonApiObject('http://openc3-cosmos-cmd-tlm-api:2901', 1.0)
49
49
  # server.cmd(*args)
50
50
  #
51
- class JsonApiObject
51
+ class JsonApiObject
52
52
  attr_reader :request_data
53
53
  attr_reader :response_data
54
54
 
@@ -64,16 +64,29 @@ module OpenC3
64
64
  @response_data = ""
65
65
  @url = url
66
66
  @log = [nil, nil, nil]
67
- @authentication = authentication.nil? ? OpenC3Authentication.new() : authentication
67
+ @authentication = authentication.nil? ? generate_auth() : authentication
68
68
  @timeout = timeout
69
69
  @shutdown = false
70
70
  end
71
71
 
72
+ # generate the auth object
73
+ def generate_auth
74
+ if ENV['OPENC3_API_TOKEN'].nil? and ENV['OPENC3_API_USER'].nil?
75
+ if ENV['OPENC3_API_PASSWORD'] || ENV['OPENC3_SERVICE_PASSWORD']
76
+ return OpenC3Authentication.new()
77
+ else
78
+ return nil
79
+ end
80
+ else
81
+ return OpenC3KeycloakAuthentication.new(ENV['OPENC3_KEYCLOAK_URL'])
82
+ end
83
+ end
84
+
72
85
  # Forwards all method calls to the remote service.
73
86
  #
74
87
  # @param method_params [Array] Array of parameters to pass to the method
75
88
  # @param keyword_params [Hash<Symbol, Variable>] Hash of keyword parameters
76
- # @return The result of the method call.
89
+ # @return The result of the method call.
77
90
  def request(*method_params, **keyword_params)
78
91
  raise JsonApiError, "Shutdown" if @shutdown
79
92
  method = method_params[0]
@@ -142,12 +155,20 @@ module OpenC3
142
155
  elsif headers.is_a?(Hash) == false
143
156
  raise JsonApiError, "incorrect type for keyword 'headers' MUST be Hash: #{headers}"
144
157
  end
145
-
158
+
146
159
  headers['Content-Type'] = 'application/json' if kwargs[:json]
147
- return headers.update({
148
- 'User-Agent' => USER_AGENT,
149
- 'Authorization' => @authentication.token(),
150
- })
160
+ token = kwargs[:token]
161
+ token = @authentication.token if @authentication and not token
162
+ if token
163
+ return headers.update({
164
+ 'User-Agent' => USER_AGENT,
165
+ 'Authorization' => token,
166
+ })
167
+ else
168
+ return headers.update({
169
+ 'User-Agent' => USER_AGENT,
170
+ })
171
+ end
151
172
  end
152
173
 
153
174
  # NOTE: This is a helper method and should not be called directly
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'thread'
@@ -298,6 +298,11 @@ module OpenC3
298
298
  response = JsonRpcErrorResponse.new(
299
299
  JsonRpcError.new(error_code, error.message, error), request.id
300
300
  )
301
+ elsif HazardousError === error
302
+ error_code = JsonRpcError::ErrorCode::HAZARDOUS_ERROR
303
+ response = JsonRpcErrorResponse.new(
304
+ JsonRpcError.new(error_code, error.message, error), request.id
305
+ )
301
306
  else
302
307
  error_code = JsonRpcError::ErrorCode::OTHER_ERROR
303
308
  response = JsonRpcErrorResponse.new(
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3'
@@ -65,7 +65,8 @@ module OpenC3
65
65
  connect() if !@http
66
66
  json_rpc_request = JsonRpcRequest.new(method_name, method_params, keyword_params, @id)
67
67
  data = json_rpc_request.to_json(:allow_nan => true)
68
- response_body = make_request(data: data)
68
+ token = keyword_params[:token]
69
+ response_body = make_request(data: data, token: token)
69
70
  if !response_body or response_body.to_s.length < 1
70
71
  disconnect()
71
72
  else
@@ -79,13 +80,21 @@ module OpenC3
79
80
 
80
81
  private
81
82
 
82
- #
83
- def make_request(data:)
84
- headers = {
85
- 'User-Agent' => USER_AGENT,
86
- 'Content-Type' => 'application/json-rpc',
87
- 'Authorization' => @authentication.token(),
88
- }
83
+ #
84
+ def make_request(data:, token: nil)
85
+ token = @authentication.token if @authentication and not token
86
+ if token
87
+ headers = {
88
+ 'User-Agent' => USER_AGENT,
89
+ 'Content-Type' => 'application/json-rpc',
90
+ 'Authorization' => token,
91
+ }
92
+ else
93
+ headers = {
94
+ 'User-Agent' => USER_AGENT,
95
+ 'Content-Type' => 'application/json-rpc',
96
+ }
97
+ end
89
98
  begin
90
99
  @log[0] = "Request: #{@uri.to_s} #{USER_AGENT} #{data.to_s}"
91
100
  STDOUT.puts @log[0] if JsonDRb.debug?
@@ -119,19 +119,19 @@ end
119
119
 
120
120
  class Time
121
121
  def as_json(options = nil) #:nodoc:
122
- to_json(options).remove_quotes
122
+ self.to_s
123
123
  end
124
124
  end
125
125
 
126
126
  class Date
127
127
  def as_json(options = nil) #:nodoc:
128
- to_json(options).remove_quotes
128
+ self.to_s
129
129
  end
130
130
  end
131
131
 
132
132
  class DateTime
133
133
  def as_json(options = nil) #:nodoc:
134
- to_json(options).remove_quotes
134
+ self.to_s
135
135
  end
136
136
  end
137
137
 
@@ -381,6 +381,8 @@ module OpenC3
381
381
  INTERNAL_ERROR = -32603
382
382
  AUTH_ERROR = -32500
383
383
  FORBIDDEN_ERROR = -32501
384
+ HAZARDOUS_ERROR = -32502
385
+ # Server error reserved: -32000 to -32099
384
386
  OTHER_ERROR = -1
385
387
  end
386
388
 
@@ -46,7 +46,7 @@ module OpenC3
46
46
  cycle_hour = nil,
47
47
  cycle_minute = nil,
48
48
  enforce_time_order = true,
49
- buffer_depth = 10
49
+ buffer_depth = 60 # Default assumes 1 minute of 1Hz data
50
50
  )
51
51
  super(
52
52
  remote_log_directory,
@@ -116,6 +116,7 @@ module OpenC3
116
116
  @cycle_minute = ConfigParser.handle_nil(cycle_minute)
117
117
  @cycle_minute = Integer(@cycle_minute) if @cycle_minute
118
118
  @enforce_time_order = ConfigParser.handle_true_false(enforce_time_order)
119
+ @out_of_order = false
119
120
  @mutex = Mutex.new
120
121
  @file = nil
121
122
  @file_size = 0
@@ -266,6 +267,7 @@ module OpenC3
266
267
  @file_size = 0
267
268
 
268
269
  @start_time = Time.now.utc
270
+ @out_of_order = false
269
271
  @first_time = nil
270
272
  @last_time = nil
271
273
  @previous_time_nsec_since_epoch = nil
@@ -287,8 +289,12 @@ module OpenC3
287
289
  Logger.debug("Log writer start new file due to cycle size #{@cycle_size}")
288
290
  start_new_file()
289
291
  elsif @enforce_time_order and @previous_time_nsec_since_epoch and (@previous_time_nsec_since_epoch > time_nsec_since_epoch)
290
- Logger.debug("Log writer start new file due to out of order time: #{Time.from_nsec_from_epoch(@previous_time_nsec_since_epoch)} #{Time.from_nsec_from_epoch(time_nsec_since_epoch)}")
291
- start_new_file()
292
+ # Warning: Creating new files here can cause lots of files to be created if packets make it through out of order
293
+ # Changed to just a error to prevent file thrashing
294
+ unless @out_of_order
295
+ Logger.error("Log writer out of order time detected (increase buffer depth?): #{Time.from_nsec_from_epoch(@previous_time_nsec_since_epoch)} #{Time.from_nsec_from_epoch(time_nsec_since_epoch)}")
296
+ @out_of_order = true
297
+ end
292
298
  end
293
299
  end
294
300
  @last_offsets[redis_topic] = redis_offset if redis_topic and redis_offset # This is needed for the redis offset marker entry at the end of the log file
@@ -17,7 +17,7 @@
17
17
  # All changes Copyright 2022, OpenC3, Inc.
18
18
  # All Rights Reserved
19
19
  #
20
- # This file may also be used under the terms of a commercial license
20
+ # This file may also be used under the terms of a commercial license
21
21
  # if purchased from OpenC3, Inc.
22
22
 
23
23
  require 'openc3/models/target_model'
@@ -49,12 +49,12 @@ module OpenC3
49
49
  ].each do |prefix, retain_time|
50
50
  next unless retain_time
51
51
  time = start_time - retain_time
52
- oldest_list = BucketUtilities.list_files_before_time(ENV['OPENC3_LOGS_BUCKET'], prefix, time)
52
+ oldest_list = BucketUtilities.files_between_time(ENV['OPENC3_LOGS_BUCKET'], prefix, nil, time)
53
53
  if oldest_list.length > 0
54
54
  @state = 'DELETING_OBJECTS'
55
55
  oldest_list.each_slice(1000) do |slice|
56
56
  bucket.delete_objects(bucket: ENV['OPENC3_LOGS_BUCKET'], keys: slice)
57
- Logger.info("Deleted #{slice.length} #{target_name} log files")
57
+ @logger.info("Deleted #{slice.length} #{target_name} log files")
58
58
  end
59
59
  end
60
60
  end
@@ -55,7 +55,7 @@ module OpenC3
55
55
  LimitsEventTopic.sync_system_thread_body(scope: @scope)
56
56
  rescue => e
57
57
  @error = e
58
- Logger.error("Decom error: #{e.formatted}")
58
+ @logger.error("Decom error: #{e.formatted}")
59
59
  end
60
60
  end
61
61
  end
@@ -68,7 +68,7 @@ module OpenC3
68
68
 
69
69
  packet = System.telemetry.packet(target_name, packet_name)
70
70
  packet.stored = ConfigParser.handle_true_false(msg_hash["stored"])
71
- packet.received_time = Time.from_nsec_from_epoch(msg_hash["time"].to_i)
71
+ packet.received_time = Time.from_nsec_from_epoch(msg_hash["received_time"].to_i)
72
72
  packet.received_count = msg_hash["received_count"].to_i
73
73
  packet.buffer = msg_hash["buffer"]
74
74
  packet.check_limits(System.limits_set) # Process all the limits and call the limits_change_callback (as necessary)
@@ -99,9 +99,9 @@ module OpenC3
99
99
  if log_change
100
100
  case item.limits.state
101
101
  when :BLUE, :GREEN, :GREEN_LOW, :GREEN_HIGH
102
- Logger.info message
102
+ @logger.info message
103
103
  when :YELLOW, :YELLOW_LOW, :YELLOW_HIGH
104
- Logger.warn message
104
+ @logger.warn message
105
105
  when :RED, :RED_LOW, :RED_HIGH
106
106
  notification = NotificationModel.new(
107
107
  time: time_nsec,
@@ -111,7 +111,7 @@ module OpenC3
111
111
  body: "Item went into #{item.limits.state} limit status."
112
112
  )
113
113
  NotificationsTopic.write_notification(notification.as_json(:allow_nan => true), scope: @scope)
114
- Logger.error message
114
+ @logger.error message
115
115
  end
116
116
  end
117
117
 
@@ -126,9 +126,9 @@ module OpenC3
126
126
  item.limits.response.call(packet, item, old_limits_state)
127
127
  rescue Exception => e
128
128
  @error = e
129
- Logger.error "#{packet.target_name} #{packet.packet_name} #{item.name} Limits Response Exception!"
130
- Logger.error "Called with old_state = #{old_limits_state}, new_state = #{item.limits.state}"
131
- Logger.error e.formatted
129
+ @logger.error "#{packet.target_name} #{packet.packet_name} #{item.name} Limits Response Exception!"
130
+ @logger.error "Called with old_state = #{old_limits_state}, new_state = #{item.limits.state}"
131
+ @logger.error e.formatted
132
132
  end
133
133
  end
134
134