openc3 5.5.0.pre.beta0 → 5.5.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.
Potentially problematic release.
This version of openc3 might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/bin/openc3cli +58 -74
- data/data/config/item_modifiers.yaml +1 -1
- data/data/config/plugins.yaml +5 -0
- data/data/config/widgets.yaml +13 -11
- data/lib/openc3/api/cmd_api.rb +43 -17
- data/lib/openc3/api/tlm_api.rb +37 -4
- data/lib/openc3/bridge/bridge.rb +3 -3
- data/lib/openc3/bridge/bridge_config.rb +68 -20
- data/lib/openc3/interfaces/interface.rb +8 -0
- data/lib/openc3/microservices/decom_microservice.rb +0 -3
- data/lib/openc3/microservices/interface_microservice.rb +2 -0
- data/lib/openc3/microservices/reaction_microservice.rb +0 -1
- data/lib/openc3/models/cvt_model.rb +1 -2
- data/lib/openc3/models/metadata_model.rb +1 -1
- data/lib/openc3/models/microservice_model.rb +1 -1
- data/lib/openc3/models/note_model.rb +1 -1
- data/lib/openc3/models/plugin_model.rb +14 -7
- data/lib/openc3/models/timeline_model.rb +1 -1
- data/lib/openc3/models/trigger_group_model.rb +1 -1
- data/lib/openc3/packets/packet_item.rb +1 -1
- data/lib/openc3/script/storage.rb +5 -5
- data/lib/openc3/streams/web_socket_client_stream.rb +0 -1
- data/lib/openc3/tools/table_manager/table_manager_core.rb +1 -2
- data/lib/openc3/utilities/aws_bucket.rb +22 -4
- data/lib/openc3/utilities/bucket_file_cache.rb +3 -2
- data/lib/openc3/utilities/bucket_utilities.rb +1 -1
- data/lib/openc3/utilities/cli_generator.rb +210 -0
- data/lib/openc3/utilities/local_mode.rb +2 -2
- data/lib/openc3/utilities/target_file.rb +43 -32
- data/lib/openc3/version.rb +5 -5
- data/templates/conversion/conversion.rb +43 -0
- data/templates/limits_response/response.rb +51 -0
- data/templates/microservice/microservices/TEMPLATE/microservice.rb +62 -0
- data/templates/plugin/plugin.txt +1 -0
- metadata +19 -15
- data/templates/plugin-template/plugin.txt +0 -9
- /data/templates/{plugin-template → plugin}/LICENSE.txt +0 -0
- /data/templates/{plugin-template → plugin}/README.md +0 -0
- /data/templates/{plugin-template → plugin}/Rakefile +0 -0
- /data/templates/{plugin-template → plugin}/plugin.gemspec +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/cmd.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/cmd_tlm/tlm.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/lib/target.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/procedures/procedure.rb +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/screens/status.txt +0 -0
- /data/templates/{plugin-template → target}/targets/TARGET/target.txt +0 -0
@@ -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/utilities/logger'
|
@@ -30,28 +30,55 @@ module OpenC3
|
|
30
30
|
# @return [Hash<String, Interface>] Routers hash
|
31
31
|
attr_accessor :routers
|
32
32
|
|
33
|
-
def initialize(filename)
|
33
|
+
def initialize(filename, existing_variables = {})
|
34
34
|
@interfaces = {}
|
35
35
|
@routers = {}
|
36
|
-
process_file(filename)
|
36
|
+
process_file(filename, existing_variables)
|
37
37
|
end
|
38
38
|
|
39
39
|
def self.generate_default(filename)
|
40
40
|
default_config = <<~EOF
|
41
|
-
|
42
|
-
|
43
|
-
# INTERFACE <Interface Name> <Interface File> <Interface Params...>
|
44
|
-
# INTERFACE <Interface Name> serial_interface.rb <Write Port> <Read Port> <Baud Rate> <Parity ODD/EVEN/NONE> <Stop Bits> <Write Timeout> <Read Timeout> <Protocol Name> <Protocol Params>
|
45
|
-
# INTERFACE <Interface Name> serial_interface.rb <Write Port> <Read Port> <Baud Rate> <Parity ODD/EVEN/NONE> <Stop Bits> <Write Timeout> <Read Timeout> BURST <Discard Leading Bytes> <Sync Pattern> <Add Sync On Write>
|
46
|
-
# INTERFACE SERIAL_INT serial_interface.rb /dev/ttyS1 /dev/ttyS1 38400 ODD 1 10.0 nil BURST 4 0xDEADBEEF
|
47
|
-
INTERFACE SERIAL_INT serial_interface.rb COM1 COM1 9600 NONE 1 10.0 nil BURST
|
41
|
+
# Write serial port name
|
42
|
+
VARIABLE write_port_name COM1
|
48
43
|
#{' '}
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
44
|
+
# Read serial port name
|
45
|
+
VARIABLE read_port_name COM1
|
46
|
+
#{' '}
|
47
|
+
# Baud Rate
|
48
|
+
VARIABLE baud_rate 115200
|
49
|
+
#{' '}
|
50
|
+
# Parity - NONE, ODD, or EVEN
|
51
|
+
VARIABLE parity NONE
|
52
|
+
#{' '}
|
53
|
+
# Stop bits - 0, 1, or 2
|
54
|
+
VARIABLE stop_bits 1
|
55
|
+
#{' '}
|
56
|
+
# Write Timeout
|
57
|
+
VARIABLE write_timeout 10.0
|
58
|
+
#{' '}
|
59
|
+
# Read Timeout
|
60
|
+
VARIABLE read_timeout nil
|
61
|
+
#{' '}
|
62
|
+
# Flow Control - NONE, or RTSCTS
|
63
|
+
VARIABLE flow_control NONE
|
64
|
+
#{' '}
|
65
|
+
# Data bits per word - Typically 8
|
66
|
+
VARIABLE data_bits 8
|
67
|
+
#{' '}
|
68
|
+
# Port to listen for connections from COSMOS - Plugin must match
|
69
|
+
VARIABLE router_port 2950
|
70
|
+
#{' '}
|
71
|
+
# Port to listen on for connections from COSMOS. Defaults to localhost for security. Will need to be opened
|
72
|
+
# if COSMOS is on another machine.
|
73
|
+
VARIABLE router_listen_address 127.0.0.1
|
74
|
+
#{' '}
|
75
|
+
INTERFACE SERIAL_INT serial_interface.rb <%= write_port_name %> <%= read_port_name %> <%= baud_rate %> <%= parity %> <%= stop_bits %> <%= write_timeout %> <%= read_timeout %>
|
76
|
+
OPTION FLOW_CONTROL <%= flow_control %>
|
77
|
+
OPTION DATA_BITS <%= data_bits %>
|
78
|
+
#{' '}
|
79
|
+
ROUTER SERIAL_ROUTER tcpip_server_interface.rb <%= router_port %> <%= router_port %> 10.0 nil BURST
|
80
|
+
ROUTE SERIAL_INT
|
81
|
+
OPTION LISTEN_ADDRESS <%= router_listen_address %>
|
55
82
|
#{' '}
|
56
83
|
EOF
|
57
84
|
|
@@ -66,18 +93,39 @@ module OpenC3
|
|
66
93
|
# Processes a file and adds in the configuration defined in the file
|
67
94
|
#
|
68
95
|
# @param filename [String] The name of the configuration file to parse
|
69
|
-
|
70
|
-
# recursively
|
71
|
-
def process_file(filename, recursive = false)
|
96
|
+
def process_file(filename, existing_variables = {})
|
72
97
|
current_interface_or_router = nil
|
73
98
|
current_type = nil
|
74
99
|
current_interface_log_added = false
|
75
100
|
|
76
101
|
Logger.info "Processing Bridge configuration in file: #{File.expand_path(filename)}"
|
77
102
|
|
103
|
+
variables = {}
|
78
104
|
parser = ConfigParser.new
|
79
|
-
parser.parse_file(filename
|
105
|
+
parser.parse_file(filename,
|
106
|
+
false,
|
107
|
+
true,
|
108
|
+
false) do |keyword, params|
|
80
109
|
case keyword
|
110
|
+
when 'VARIABLE'
|
111
|
+
usage = "#{keyword} <Variable Name> <Default Value>"
|
112
|
+
parser.verify_num_parameters(2, nil, usage)
|
113
|
+
variable_name = params[0]
|
114
|
+
value = params[1..-1].join(" ")
|
115
|
+
variables[variable_name] = value
|
116
|
+
if existing_variables && existing_variables.key?(variable_name)
|
117
|
+
variables[variable_name] = existing_variables[variable_name]
|
118
|
+
end
|
119
|
+
# Ignore everything else during phase 1
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
parser = ConfigParser.new
|
124
|
+
parser.parse_file(filename, false, true, true, variables) do |keyword, params|
|
125
|
+
case keyword
|
126
|
+
|
127
|
+
when 'VARIABLE'
|
128
|
+
# Ignore during this pass
|
81
129
|
|
82
130
|
when 'INTERFACE'
|
83
131
|
usage = "INTERFACE <Name> <Filename> <Specific Parameters>"
|
@@ -25,6 +25,11 @@ require 'openc3/io/raw_logger_pair'
|
|
25
25
|
require 'openc3/utilities/secrets'
|
26
26
|
|
27
27
|
module OpenC3
|
28
|
+
# Define a class to allow interfaces and protocols to reject commands without
|
29
|
+
# disconnecting the interface
|
30
|
+
class WriteRejectError < StandardError
|
31
|
+
end
|
32
|
+
|
28
33
|
# Defines all the attributes and methods common to all interface classes
|
29
34
|
# used by OpenC3.
|
30
35
|
class Interface
|
@@ -330,6 +335,9 @@ module OpenC3
|
|
330
335
|
else
|
331
336
|
@write_mutex.synchronize { yield }
|
332
337
|
end
|
338
|
+
rescue WriteRejectError => err
|
339
|
+
Logger.error("#{@name}: Write rejected by interface: #{err.message}")
|
340
|
+
raise err
|
333
341
|
rescue Exception => err
|
334
342
|
Logger.error("#{@name}: Error writing to interface")
|
335
343
|
disconnect()
|
@@ -95,7 +95,6 @@ module OpenC3
|
|
95
95
|
# @param log_change [Boolean] Whether to log this limits change event
|
96
96
|
def limits_change_callback(packet, item, old_limits_state, value, log_change)
|
97
97
|
return if @cancel_thread
|
98
|
-
start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
99
98
|
packet_time = packet.packet_time
|
100
99
|
message = "#{packet.target_name} #{packet.packet_name} #{item.name} = #{value} is #{item.limits.state}"
|
101
100
|
message << " (#{packet.packet_time.sys.formatted})" if packet_time
|
@@ -136,8 +135,6 @@ module OpenC3
|
|
136
135
|
@logger.error e.formatted
|
137
136
|
end
|
138
137
|
end
|
139
|
-
|
140
|
-
diff = Process.clock_gettime(Process::CLOCK_MONOTONIC) - start # seconds as a float
|
141
138
|
end
|
142
139
|
end
|
143
140
|
end
|
@@ -264,7 +264,6 @@ module OpenC3
|
|
264
264
|
when 'trigger'
|
265
265
|
process_enabled_trigger(data: data)
|
266
266
|
end
|
267
|
-
current_time = Time.now.to_i
|
268
267
|
rescue StandardError => e
|
269
268
|
@logger.error "ReactionWorker-#{@ident} failed to evaluate kind: #{kind} data: #{data}\n#{e.formatted}"
|
270
269
|
end
|
@@ -240,11 +240,10 @@ module OpenC3
|
|
240
240
|
# return an ordered array of hash with keys
|
241
241
|
def self._parse_item(lookups, overrides, item, scope:)
|
242
242
|
target_name, packet_name, item_name, value_type = item.split('__')
|
243
|
-
raise ArgumentError, "items must be formatted as TGT__PKT__ITEM__TYPE" if target_name.nil? || packet_name.nil? || item_name.nil? || value_type.nil?
|
244
243
|
|
245
244
|
# We build lookup keys by including all the less formatted types to gracefully degrade lookups
|
246
245
|
# This allows the user to specify WITH_UNITS and if there is no conversions it will simply return the RAW value
|
247
|
-
case value_type
|
246
|
+
case value_type
|
248
247
|
when 'RAW'
|
249
248
|
keys = [item_name]
|
250
249
|
when 'CONVERTED'
|
@@ -69,7 +69,7 @@ module OpenC3
|
|
69
69
|
if @color.nil?
|
70
70
|
@color = '#%06x' % (rand * 0xffffff)
|
71
71
|
end
|
72
|
-
unless @color =~ /(#*)([0-
|
72
|
+
unless @color =~ /(#*)([0-9a-fA-F]{6})/
|
73
73
|
raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
|
74
74
|
end
|
75
75
|
@color = "##{@color}" unless @color.start_with?('#')
|
@@ -163,7 +163,7 @@ module OpenC3
|
|
163
163
|
parser.verify_num_parameters(1, 2, usage)
|
164
164
|
begin
|
165
165
|
@ports << [Integer(parameters[0])]
|
166
|
-
rescue
|
166
|
+
rescue # In case Integer fails
|
167
167
|
raise ConfigParser::Error.new(parser, "Port must be an integer: #{parameters[0]}", usage)
|
168
168
|
end
|
169
169
|
protocol = ConfigParser.handle_nil(parameters[1])
|
@@ -78,7 +78,7 @@ module OpenC3
|
|
78
78
|
if @color.nil?
|
79
79
|
@color = '#%06x' % (rand * 0xffffff)
|
80
80
|
end
|
81
|
-
unless @color =~ /(#*)([0-
|
81
|
+
unless @color =~ /(#*)([0-9a-fA-F]{6})/
|
82
82
|
raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
|
83
83
|
end
|
84
84
|
@color = "##{@color}" unless @color.start_with?('#')
|
@@ -72,7 +72,7 @@ module OpenC3
|
|
72
72
|
temp_dir = Dir.mktmpdir
|
73
73
|
tf = nil
|
74
74
|
begin
|
75
|
-
if File.
|
75
|
+
if File.exist?(gem_file_path)
|
76
76
|
# Load gem to internal gem server
|
77
77
|
OpenC3::GemModel.put(gem_file_path, gem_install: false, scope: scope) unless validate_only
|
78
78
|
else
|
@@ -122,7 +122,6 @@ module OpenC3
|
|
122
122
|
if existing_variables && existing_variables.key?(variable_name)
|
123
123
|
variables[variable_name] = existing_variables[variable_name]
|
124
124
|
end
|
125
|
-
# Ignore everything else during phase 1
|
126
125
|
end
|
127
126
|
end
|
128
127
|
|
@@ -162,14 +161,21 @@ module OpenC3
|
|
162
161
|
gem_path = File.join(temp_dir, "gem")
|
163
162
|
FileUtils.mkdir_p(gem_path)
|
164
163
|
pkg = Gem::Package.new(gem_file_path)
|
165
|
-
needs_dependencies = pkg.spec.runtime_dependencies.length > 0
|
166
164
|
pkg.extract_files(gem_path)
|
167
165
|
Dir[File.join(gem_path, '**/screens/*.txt')].each do |filename|
|
168
166
|
if File.basename(filename) != File.basename(filename).downcase
|
169
|
-
raise "Invalid screen
|
167
|
+
raise "Invalid screen filename: #{filename}. Screen filenames must be lowercase."
|
170
168
|
end
|
171
169
|
end
|
170
|
+
needs_dependencies = pkg.spec.runtime_dependencies.length > 0
|
172
171
|
needs_dependencies = true if Dir.exist?(File.join(gem_path, 'lib'))
|
172
|
+
# If needs_dependencies hasn't already been set we need to scan the plugin.txt
|
173
|
+
# to see if they've explicitly set the NEEDS_DEPENDENCIES keyword
|
174
|
+
unless needs_dependencies
|
175
|
+
if plugin_hash['plugin_txt_lines'].join("\n").include?('NEEDS_DEPENDENCIES')
|
176
|
+
needs_dependencies = true
|
177
|
+
end
|
178
|
+
end
|
173
179
|
if needs_dependencies
|
174
180
|
plugin_model.needs_dependencies = true
|
175
181
|
plugin_model.update unless validate_only
|
@@ -198,7 +204,7 @@ module OpenC3
|
|
198
204
|
current_model = nil
|
199
205
|
parser.parse_file(plugin_txt_path, false, true, true, variables) do |keyword, params|
|
200
206
|
case keyword
|
201
|
-
when 'VARIABLE'
|
207
|
+
when 'VARIABLE', 'NEEDS_DEPENDENCIES'
|
202
208
|
# Ignore during phase 2
|
203
209
|
when 'TARGET', 'INTERFACE', 'ROUTER', 'MICROSERVICE', 'TOOL', 'WIDGET'
|
204
210
|
if current_model
|
@@ -206,12 +212,13 @@ module OpenC3
|
|
206
212
|
current_model.deploy(gem_path, variables, validate_only: validate_only)
|
207
213
|
current_model = nil
|
208
214
|
end
|
209
|
-
current_model = OpenC3.const_get((keyword.capitalize + 'Model').intern).handle_config(parser,
|
215
|
+
current_model = OpenC3.const_get((keyword.capitalize + 'Model').intern).handle_config(parser,
|
216
|
+
keyword, params, plugin: plugin_model.name, needs_dependencies: needs_dependencies, scope: scope)
|
210
217
|
else
|
211
218
|
if current_model
|
212
219
|
current_model.handle_config(parser, keyword, params)
|
213
220
|
else
|
214
|
-
raise "Invalid keyword #{keyword} in plugin.txt"
|
221
|
+
raise "Invalid keyword '#{keyword}' in plugin.txt"
|
215
222
|
end
|
216
223
|
end
|
217
224
|
end
|
@@ -91,7 +91,7 @@ module OpenC3
|
|
91
91
|
if color.nil?
|
92
92
|
color = '#%06x' % (rand * 0xffffff)
|
93
93
|
end
|
94
|
-
valid_color = color =~ /[0-
|
94
|
+
valid_color = color =~ /[0-9a-fA-F]{6}/
|
95
95
|
if valid_color.nil?
|
96
96
|
raise RuntimeError.new "invalid color but in hex format. #FF0000"
|
97
97
|
end
|
@@ -92,7 +92,7 @@ module OpenC3
|
|
92
92
|
if color.nil?
|
93
93
|
color = '#%06x' % (rand * 0xffffff)
|
94
94
|
end
|
95
|
-
valid_color = color =~ /[0-
|
95
|
+
valid_color = color =~ /[0-9a-fA-F]{6}/
|
96
96
|
if valid_color.nil?
|
97
97
|
raise TriggerGroupInputError.new "invalid color must be in hex format. #FF0000"
|
98
98
|
end
|
@@ -80,7 +80,7 @@ module OpenC3
|
|
80
80
|
|
81
81
|
# @return [Hash] Whether or not messages should be printed for this state.
|
82
82
|
# Given as STATE_NAME => true / false.
|
83
|
-
|
83
|
+
attr_reader :messages_disabled
|
84
84
|
|
85
85
|
# Colors associated with states
|
86
86
|
# @return [Hash] State colors given as STATE_NAME => COLOR
|
@@ -77,7 +77,7 @@ module OpenC3
|
|
77
77
|
else
|
78
78
|
request.body_stream = io_or_string
|
79
79
|
end
|
80
|
-
|
80
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
|
81
81
|
http.request(request) do |response|
|
82
82
|
response.value() # Raises an HTTP error if the response is not 2xx (success)
|
83
83
|
return response
|
@@ -157,17 +157,17 @@ module OpenC3
|
|
157
157
|
if $openc3_in_cluster
|
158
158
|
case ENV['OPENC3_CLOUD']
|
159
159
|
when 'local'
|
160
|
-
|
160
|
+
URI.parse("http://openc3-minio:9000" + url)
|
161
161
|
when 'aws'
|
162
|
-
|
162
|
+
URI.parse("https://s3.#{ENV['AWS_REGION']}.amazonaws.com" + url)
|
163
163
|
when 'gcp'
|
164
|
-
|
164
|
+
URI.parse("https://storage.googleapis.com" + url)
|
165
165
|
# when 'azure'
|
166
166
|
else
|
167
167
|
raise "Unknown cloud #{ENV['OPENC3_CLOUD']}"
|
168
168
|
end
|
169
169
|
else
|
170
|
-
|
170
|
+
URI.parse($api_server.generate_url + url)
|
171
171
|
end
|
172
172
|
end
|
173
173
|
|
@@ -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'
|
@@ -148,7 +148,6 @@ module OpenC3
|
|
148
148
|
}
|
149
149
|
col = 0
|
150
150
|
row = 0
|
151
|
-
num_cols = table.num_columns
|
152
151
|
table.sorted_items.each_with_index do |item, index|
|
153
152
|
next if item.hidden
|
154
153
|
if table.num_columns == 1
|
@@ -111,7 +111,12 @@ module OpenC3
|
|
111
111
|
token = nil
|
112
112
|
result = []
|
113
113
|
while true
|
114
|
-
resp = @client.list_objects_v2(
|
114
|
+
resp = @client.list_objects_v2({
|
115
|
+
bucket: bucket,
|
116
|
+
max_keys: max_request,
|
117
|
+
prefix: prefix,
|
118
|
+
continuation_token: token
|
119
|
+
})
|
115
120
|
result.concat(resp.contents)
|
116
121
|
break if result.length >= max_total
|
117
122
|
break unless resp.is_truncated
|
@@ -119,12 +124,12 @@ module OpenC3
|
|
119
124
|
end
|
120
125
|
# Array of objects with key and size methods
|
121
126
|
result
|
122
|
-
rescue Aws::S3::Errors::NoSuchBucket
|
127
|
+
rescue Aws::S3::Errors::NoSuchBucket
|
123
128
|
raise NotFound, "Bucket '#{bucket}' does not exist."
|
124
129
|
end
|
125
130
|
|
126
131
|
# Lists the files under a specified path
|
127
|
-
def list_files(bucket:, path:, only_directories: false)
|
132
|
+
def list_files(bucket:, path:, only_directories: false, include_head: false)
|
128
133
|
# Trailing slash is important in AWS S3 when listing files
|
129
134
|
# See https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/S3/Types/ListObjectsV2Output.html#common_prefixes-instance_method
|
130
135
|
if path[-1] != '/'
|
@@ -158,6 +163,9 @@ module OpenC3
|
|
158
163
|
item['name'] = aws_item.key.split('/')[-1]
|
159
164
|
item['modified'] = aws_item.last_modified
|
160
165
|
item['size'] = aws_item.size
|
166
|
+
if include_head
|
167
|
+
item['head'] = head_object(bucket: bucket, key: aws_item.key)
|
168
|
+
end
|
161
169
|
files << item
|
162
170
|
end
|
163
171
|
result = [dirs, files]
|
@@ -166,10 +174,20 @@ module OpenC3
|
|
166
174
|
token = resp.next_continuation_token
|
167
175
|
end
|
168
176
|
result
|
169
|
-
rescue Aws::S3::Errors::NoSuchBucket
|
177
|
+
rescue Aws::S3::Errors::NoSuchBucket
|
170
178
|
raise NotFound, "Bucket '#{bucket}' does not exist."
|
171
179
|
end
|
172
180
|
|
181
|
+
# get metadata for a specific object
|
182
|
+
def head_object(bucket:, key:)
|
183
|
+
head = @client.head_object({
|
184
|
+
bucket: bucket,
|
185
|
+
key: key
|
186
|
+
})
|
187
|
+
rescue Aws::S3::Errors::NotFound => error
|
188
|
+
raise NotFound, "Object: #{bucket}/#{key}"
|
189
|
+
end
|
190
|
+
|
173
191
|
# put_object fires off the request to store but does not confirm
|
174
192
|
def put_object(bucket:, key:, body:, content_type: nil, cache_control: nil, metadata: nil)
|
175
193
|
@client.put_object(bucket: bucket, key: key, body: body,
|
@@ -57,10 +57,10 @@ class BucketFile
|
|
57
57
|
cmd_or_tlm = path_split[2].to_s.upcase
|
58
58
|
target_name = path_split[3].to_s.upcase
|
59
59
|
if stream_mode == 'RAW'
|
60
|
-
type = (
|
60
|
+
type = (cmd_or_tlm == 'CMD') ? 'COMMAND' : 'TELEMETRY'
|
61
61
|
else
|
62
62
|
if stream_mode == 'DECOM'
|
63
|
-
type = (
|
63
|
+
type = (cmd_or_tlm == 'CMD') ? 'DECOMCMD' : 'DECOM'
|
64
64
|
else
|
65
65
|
type = stream_mode # REDUCED_MINUTE, REDUCED_HOUR, or REDUCED_DAY
|
66
66
|
end
|
@@ -156,6 +156,7 @@ class BucketFileCache
|
|
156
156
|
@current_disk_usage = 0
|
157
157
|
@queued_bucket_files = []
|
158
158
|
@bucket_file_hash = {}
|
159
|
+
bucket_file = nil
|
159
160
|
|
160
161
|
@thread = Thread.new do
|
161
162
|
client = OpenC3::Bucket.getClient()
|
@@ -162,7 +162,7 @@ module OpenC3
|
|
162
162
|
|
163
163
|
def self.get_file_times(bucket_path)
|
164
164
|
basename = File.basename(bucket_path)
|
165
|
-
file_start_timestamp, file_end_timestamp,
|
165
|
+
file_start_timestamp, file_end_timestamp, _ = basename.split("__")
|
166
166
|
file_start_time = DateTime.strptime(file_start_timestamp, FILE_TIMESTAMP_FORMAT).to_time
|
167
167
|
file_end_time = DateTime.strptime(file_end_timestamp, FILE_TIMESTAMP_FORMAT).to_time
|
168
168
|
return file_start_time, file_end_time
|