openc3 5.1.1 → 5.2.0

Sign up to get free protection for your applications and to get access to all the features.
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