openc3 5.0.11 → 5.1.1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of openc3 might be problematic. Click here for more details.

Files changed (280) hide show
  1. checksums.yaml +4 -4
  2. data/Guardfile +3 -0
  3. data/LICENSE.txt +7 -5
  4. data/README.md +11 -9
  5. data/Rakefile +3 -0
  6. data/bin/cstol_converter +3 -0
  7. data/bin/openc3cli +29 -18
  8. data/bin/rubysloc +3 -0
  9. data/data/config/screen.yaml +10 -2
  10. data/data/config/target.yaml +1 -1
  11. data/data/config/widgets.yaml +6 -6
  12. data/ext/mkrf_conf.rb +3 -0
  13. data/ext/openc3/ext/array/array.c +3 -0
  14. data/ext/openc3/ext/buffered_file/buffered_file.c +3 -0
  15. data/ext/openc3/ext/config_parser/config_parser.c +3 -0
  16. data/ext/openc3/ext/crc/crc.c +3 -0
  17. data/ext/openc3/ext/openc3_io/openc3_io.c +3 -0
  18. data/ext/openc3/ext/packet/packet.c +3 -0
  19. data/ext/openc3/ext/platform/platform.c +3 -0
  20. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +3 -0
  21. data/ext/openc3/ext/string/string.c +3 -0
  22. data/ext/openc3/ext/structure/structure.c +3 -0
  23. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +3 -0
  24. data/ext/openc3/ext/telemetry/telemetry.c +3 -0
  25. data/lib/cosmos.rb +3 -0
  26. data/lib/cosmosc2.rb +3 -0
  27. data/lib/openc3/accessors/accessor.rb +3 -0
  28. data/lib/openc3/accessors/binary_accessor.rb +3 -0
  29. data/lib/openc3/accessors/cbor_accessor.rb +3 -0
  30. data/lib/openc3/accessors/html_accessor.rb +3 -0
  31. data/lib/openc3/accessors/json_accessor.rb +4 -1
  32. data/lib/openc3/accessors/xml_accessor.rb +3 -0
  33. data/lib/openc3/accessors.rb +3 -0
  34. data/lib/openc3/api/api.rb +3 -0
  35. data/lib/openc3/api/authorized_api.rb +3 -0
  36. data/lib/openc3/api/cmd_api.rb +6 -3
  37. data/lib/openc3/api/config_api.rb +3 -0
  38. data/lib/openc3/api/interface_api.rb +6 -2
  39. data/lib/openc3/api/limits_api.rb +54 -61
  40. data/lib/openc3/api/router_api.rb +6 -3
  41. data/lib/openc3/api/settings_api.rb +3 -0
  42. data/lib/openc3/api/target_api.rb +3 -0
  43. data/lib/openc3/api/tlm_api.rb +27 -32
  44. data/lib/openc3/bridge/bridge.rb +3 -0
  45. data/lib/openc3/bridge/bridge_config.rb +3 -0
  46. data/lib/openc3/bridge/bridge_interface_thread.rb +3 -0
  47. data/lib/openc3/bridge/bridge_router_thread.rb +3 -0
  48. data/lib/openc3/ccsds/ccsds_packet.rb +3 -0
  49. data/lib/openc3/ccsds/ccsds_parser.rb +3 -0
  50. data/lib/openc3/config/config_parser.rb +3 -0
  51. data/lib/openc3/config/meta_config_parser.rb +3 -0
  52. data/lib/openc3/conversions/conversion.rb +3 -0
  53. data/lib/openc3/conversions/generic_conversion.rb +3 -0
  54. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +3 -0
  55. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +3 -0
  56. data/lib/openc3/conversions/polynomial_conversion.rb +3 -0
  57. data/lib/openc3/conversions/processor_conversion.rb +3 -0
  58. data/lib/openc3/conversions/received_count_conversion.rb +3 -0
  59. data/lib/openc3/conversions/received_time_formatted_conversion.rb +3 -0
  60. data/lib/openc3/conversions/received_time_seconds_conversion.rb +3 -0
  61. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +3 -0
  62. data/lib/openc3/conversions/unix_time_conversion.rb +3 -0
  63. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +3 -0
  64. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +3 -0
  65. data/lib/openc3/conversions.rb +3 -0
  66. data/lib/openc3/core_ext/array.rb +3 -0
  67. data/lib/openc3/core_ext/binding.rb +3 -0
  68. data/lib/openc3/core_ext/class.rb +3 -0
  69. data/lib/openc3/core_ext/exception.rb +3 -0
  70. data/lib/openc3/core_ext/file.rb +3 -0
  71. data/lib/openc3/core_ext/hash.rb +3 -0
  72. data/lib/openc3/core_ext/io.rb +3 -0
  73. data/lib/openc3/core_ext/kernel.rb +3 -0
  74. data/lib/openc3/core_ext/math.rb +3 -0
  75. data/lib/openc3/core_ext/matrix.rb +3 -0
  76. data/lib/openc3/core_ext/objectspace.rb +3 -0
  77. data/lib/openc3/core_ext/openc3_io.rb +3 -0
  78. data/lib/openc3/core_ext/range.rb +3 -0
  79. data/lib/openc3/core_ext/socket.rb +3 -0
  80. data/lib/openc3/core_ext/string.rb +3 -0
  81. data/lib/openc3/core_ext/stringio.rb +3 -0
  82. data/lib/openc3/core_ext/tempfile.rb +3 -0
  83. data/lib/openc3/core_ext/time.rb +3 -0
  84. data/lib/openc3/core_ext.rb +3 -0
  85. data/lib/openc3/interfaces/interface.rb +3 -0
  86. data/lib/openc3/interfaces/linc_interface.rb +3 -0
  87. data/lib/openc3/interfaces/protocols/burst_protocol.rb +3 -0
  88. data/lib/openc3/interfaces/protocols/crc_protocol.rb +3 -0
  89. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +3 -0
  90. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +3 -0
  91. data/lib/openc3/interfaces/protocols/length_protocol.rb +3 -0
  92. data/lib/openc3/interfaces/protocols/override_protocol.rb +3 -0
  93. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +3 -0
  94. data/lib/openc3/interfaces/protocols/protocol.rb +3 -0
  95. data/lib/openc3/interfaces/protocols/template_protocol.rb +3 -0
  96. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +3 -0
  97. data/lib/openc3/interfaces/serial_interface.rb +3 -0
  98. data/lib/openc3/interfaces/simulated_target_interface.rb +3 -0
  99. data/lib/openc3/interfaces/stream_interface.rb +3 -0
  100. data/lib/openc3/interfaces/tcpip_client_interface.rb +3 -0
  101. data/lib/openc3/interfaces/tcpip_server_interface.rb +3 -0
  102. data/lib/openc3/interfaces/udp_interface.rb +3 -0
  103. data/lib/openc3/interfaces.rb +3 -0
  104. data/lib/openc3/io/buffered_file.rb +3 -0
  105. data/lib/openc3/io/io_multiplexer.rb +8 -0
  106. data/lib/openc3/io/json_api_object.rb +5 -2
  107. data/lib/openc3/io/json_drb.rb +3 -0
  108. data/lib/openc3/io/json_drb_object.rb +5 -2
  109. data/lib/openc3/io/json_drb_rack.rb +3 -0
  110. data/lib/openc3/io/json_rpc.rb +8 -3
  111. data/lib/openc3/io/openc3_snmp.rb +3 -0
  112. data/lib/openc3/io/posix_serial_driver.rb +3 -0
  113. data/lib/openc3/io/raw_logger.rb +3 -0
  114. data/lib/openc3/io/raw_logger_pair.rb +3 -0
  115. data/lib/openc3/io/serial_driver.rb +3 -0
  116. data/lib/openc3/io/stderr.rb +3 -0
  117. data/lib/openc3/io/stdout.rb +3 -0
  118. data/lib/openc3/io/udp_sockets.rb +3 -0
  119. data/lib/openc3/io/win32_serial_driver.rb +3 -0
  120. data/lib/openc3/logs/buffered_packet_log_reader.rb +65 -0
  121. data/lib/openc3/logs/buffered_packet_log_writer.rb +120 -0
  122. data/lib/openc3/logs/log_writer.rb +95 -40
  123. data/lib/openc3/logs/packet_log_constants.rb +9 -0
  124. data/lib/openc3/logs/packet_log_reader.rb +34 -3
  125. data/lib/openc3/logs/packet_log_writer.rb +85 -18
  126. data/lib/openc3/logs/text_log_writer.rb +9 -5
  127. data/lib/openc3/logs.rb +8 -2
  128. data/lib/openc3/microservices/cleanup_microservice.rb +18 -18
  129. data/lib/openc3/microservices/decom_microservice.rb +30 -24
  130. data/lib/openc3/microservices/interface_microservice.rb +136 -91
  131. data/lib/openc3/microservices/log_microservice.rb +35 -13
  132. data/lib/openc3/microservices/microservice.rb +16 -14
  133. data/lib/openc3/microservices/plugin_microservice.rb +3 -1
  134. data/lib/openc3/microservices/reaction_microservice.rb +4 -1
  135. data/lib/openc3/microservices/reducer_microservice.rb +332 -149
  136. data/lib/openc3/microservices/router_microservice.rb +3 -0
  137. data/lib/openc3/microservices/text_log_microservice.rb +22 -7
  138. data/lib/openc3/microservices/timeline_microservice.rb +4 -1
  139. data/lib/openc3/microservices/trigger_group_microservice.rb +3 -0
  140. data/lib/openc3/models/activity_model.rb +3 -0
  141. data/lib/openc3/models/auth_model.rb +3 -0
  142. data/lib/openc3/models/cvt_model.rb +14 -5
  143. data/lib/openc3/models/environment_model.rb +3 -0
  144. data/lib/openc3/models/gem_model.rb +30 -51
  145. data/lib/openc3/models/info_model.rb +3 -0
  146. data/lib/openc3/models/interface_model.rb +3 -0
  147. data/lib/openc3/models/interface_status_model.rb +4 -1
  148. data/lib/openc3/models/metadata_model.rb +3 -0
  149. data/lib/openc3/models/metric_model.rb +3 -0
  150. data/lib/openc3/models/microservice_model.rb +9 -6
  151. data/lib/openc3/models/microservice_status_model.rb +4 -1
  152. data/lib/openc3/models/model.rb +3 -0
  153. data/lib/openc3/models/note_model.rb +3 -0
  154. data/lib/openc3/models/notification_model.rb +3 -0
  155. data/lib/openc3/models/ping_model.rb +3 -0
  156. data/lib/openc3/models/plugin_model.rb +20 -14
  157. data/lib/openc3/models/process_status_model.rb +4 -1
  158. data/lib/openc3/models/reaction_model.rb +3 -0
  159. data/lib/openc3/models/reducer_model.rb +31 -24
  160. data/lib/openc3/models/router_model.rb +3 -0
  161. data/lib/openc3/models/router_status_model.rb +3 -0
  162. data/lib/openc3/models/scope_model.rb +3 -4
  163. data/lib/openc3/models/settings_model.rb +3 -0
  164. data/lib/openc3/models/sorted_model.rb +3 -0
  165. data/lib/openc3/models/target_model.rb +61 -94
  166. data/lib/openc3/models/timeline_model.rb +4 -1
  167. data/lib/openc3/models/tool_config_model.rb +3 -0
  168. data/lib/openc3/models/tool_model.rb +11 -9
  169. data/lib/openc3/models/trigger_group_model.rb +3 -0
  170. data/lib/openc3/models/trigger_model.rb +3 -0
  171. data/lib/openc3/models/widget_model.rb +18 -11
  172. data/lib/openc3/operators/microservice_operator.rb +3 -0
  173. data/lib/openc3/operators/operator.rb +105 -34
  174. data/lib/openc3/packets/commands.rb +3 -0
  175. data/lib/openc3/packets/json_packet.rb +87 -14
  176. data/lib/openc3/packets/limits.rb +4 -1
  177. data/lib/openc3/packets/limits_response.rb +3 -0
  178. data/lib/openc3/packets/packet.rb +5 -1
  179. data/lib/openc3/packets/packet_config.rb +3 -0
  180. data/lib/openc3/packets/packet_item.rb +9 -3
  181. data/lib/openc3/packets/packet_item_limits.rb +3 -0
  182. data/lib/openc3/packets/parsers/format_string_parser.rb +3 -0
  183. data/lib/openc3/packets/parsers/limits_parser.rb +3 -0
  184. data/lib/openc3/packets/parsers/limits_response_parser.rb +3 -0
  185. data/lib/openc3/packets/parsers/packet_item_parser.rb +3 -0
  186. data/lib/openc3/packets/parsers/packet_parser.rb +3 -0
  187. data/lib/openc3/packets/parsers/processor_parser.rb +3 -0
  188. data/lib/openc3/packets/parsers/state_parser.rb +3 -0
  189. data/lib/openc3/packets/parsers/xtce_converter.rb +3 -0
  190. data/lib/openc3/packets/parsers/xtce_parser.rb +3 -0
  191. data/lib/openc3/packets/structure.rb +3 -0
  192. data/lib/openc3/packets/structure_item.rb +3 -0
  193. data/lib/openc3/packets/telemetry.rb +3 -0
  194. data/lib/openc3/processors/processor.rb +3 -0
  195. data/lib/openc3/processors/statistics_processor.rb +3 -0
  196. data/lib/openc3/processors/watermark_processor.rb +3 -0
  197. data/lib/openc3/processors.rb +3 -0
  198. data/lib/openc3/script/api_shared.rb +35 -6
  199. data/lib/openc3/script/calendar.rb +3 -0
  200. data/lib/openc3/script/commands.rb +3 -0
  201. data/lib/openc3/script/exceptions.rb +3 -0
  202. data/lib/openc3/script/extract.rb +3 -0
  203. data/lib/openc3/script/limits.rb +3 -24
  204. data/lib/openc3/script/script.rb +11 -7
  205. data/lib/openc3/script/script_runner.rb +3 -0
  206. data/lib/openc3/script/storage.rb +33 -16
  207. data/lib/openc3/script/suite.rb +3 -0
  208. data/lib/openc3/script/suite_results.rb +3 -0
  209. data/lib/openc3/script/suite_runner.rb +3 -0
  210. data/lib/openc3/script/telemetry.rb +43 -0
  211. data/lib/openc3/script.rb +3 -0
  212. data/lib/openc3/streams/serial_stream.rb +3 -0
  213. data/lib/openc3/streams/stream.rb +3 -0
  214. data/lib/openc3/streams/tcpip_client_stream.rb +3 -0
  215. data/lib/openc3/streams/tcpip_socket_stream.rb +3 -0
  216. data/lib/openc3/system/system.rb +23 -10
  217. data/lib/openc3/system/system_config.rb +3 -0
  218. data/lib/openc3/system/target.rb +3 -0
  219. data/lib/openc3/system.rb +3 -0
  220. data/lib/openc3/tools/cmd_tlm_server/api.rb +3 -0
  221. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +3 -0
  222. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +3 -0
  223. data/lib/openc3/tools/table_manager/table.rb +3 -0
  224. data/lib/openc3/tools/table_manager/table_config.rb +3 -0
  225. data/lib/openc3/tools/table_manager/table_item.rb +3 -0
  226. data/lib/openc3/tools/table_manager/table_item_parser.rb +3 -0
  227. data/lib/openc3/tools/table_manager/table_manager_core.rb +3 -0
  228. data/lib/openc3/tools/table_manager/table_parser.rb +3 -0
  229. data/lib/openc3/tools/test_runner/test.rb +3 -0
  230. data/lib/openc3/top_level.rb +3 -0
  231. data/lib/openc3/topics/autonomic_topic.rb +3 -0
  232. data/lib/openc3/topics/calendar_topic.rb +3 -0
  233. data/lib/openc3/topics/command_decom_topic.rb +4 -1
  234. data/lib/openc3/topics/command_topic.rb +6 -1
  235. data/lib/openc3/topics/config_topic.rb +3 -0
  236. data/lib/openc3/topics/interface_topic.rb +9 -2
  237. data/lib/openc3/topics/limits_event_topic.rb +144 -10
  238. data/lib/openc3/topics/notifications_topic.rb +3 -0
  239. data/lib/openc3/topics/router_topic.rb +10 -3
  240. data/lib/openc3/topics/telemetry_decom_topic.rb +26 -20
  241. data/lib/openc3/topics/telemetry_reduced_topics.rb +92 -0
  242. data/lib/openc3/topics/telemetry_topic.rb +5 -2
  243. data/lib/openc3/topics/timeline_topic.rb +3 -0
  244. data/lib/openc3/topics/topic.rb +3 -0
  245. data/lib/openc3/utilities/authentication.rb +3 -0
  246. data/lib/openc3/utilities/authorization.rb +3 -0
  247. data/lib/openc3/utilities/aws_bucket.rb +199 -0
  248. data/lib/openc3/utilities/bucket.rb +82 -0
  249. data/lib/openc3/utilities/bucket_file_cache.rb +264 -0
  250. data/lib/openc3/utilities/bucket_utilities.rb +109 -0
  251. data/lib/openc3/utilities/crc.rb +3 -0
  252. data/lib/openc3/utilities/csv.rb +3 -0
  253. data/lib/openc3/utilities/local_bucket.rb +28 -0
  254. data/lib/openc3/utilities/local_mode.rb +47 -61
  255. data/lib/openc3/utilities/logger.rb +7 -1
  256. data/lib/openc3/utilities/message_log.rb +7 -4
  257. data/lib/openc3/utilities/metric.rb +4 -1
  258. data/lib/openc3/utilities/open_telemetry.rb +96 -0
  259. data/lib/openc3/utilities/process_manager.rb +3 -0
  260. data/lib/openc3/utilities/quaternion.rb +3 -0
  261. data/lib/openc3/utilities/ruby_lex_utils.rb +3 -0
  262. data/lib/openc3/utilities/s3_autoload.rb +3 -3
  263. data/lib/openc3/utilities/simulated_target.rb +3 -0
  264. data/lib/openc3/utilities/sleeper.rb +3 -0
  265. data/lib/openc3/utilities/store.rb +3 -0
  266. data/lib/openc3/utilities/store_autoload.rb +30 -23
  267. data/lib/openc3/utilities/target_file.rb +70 -83
  268. data/lib/openc3/utilities/zip.rb +3 -0
  269. data/lib/openc3/utilities.rb +3 -0
  270. data/lib/openc3/version.rb +6 -6
  271. data/lib/openc3/win32/excel.rb +3 -0
  272. data/lib/openc3/win32/win32.rb +3 -0
  273. data/lib/openc3/win32/win32_main.rb +3 -0
  274. data/lib/openc3.rb +3 -0
  275. data/tasks/gemfile_stats.rake +3 -0
  276. data/tasks/spec.rake +3 -0
  277. data/templates/plugin-template/plugin.gemspec +1 -1
  278. metadata +112 -6
  279. data/lib/openc3/utilities/s3.rb +0 -220
  280. data/lib/openc3/utilities/s3_file_cache.rb +0 -274
@@ -1,220 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2022 Ball Aerospace & Technologies Corp.
4
- # All Rights Reserved.
5
- #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero General Public License
8
- # as published by the Free Software Foundation; version 3 with
9
- # attribution addendums as found in the LICENSE.txt
10
- #
11
- # This program is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
15
-
16
- # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
18
- # All Rights Reserved
19
-
20
- module Aws
21
- autoload(:S3, 'openc3/utilities/s3_autoload.rb')
22
- end
23
- require 'openc3/models/reducer_model'
24
-
25
- module OpenC3
26
- class S3Utilities
27
- def self.put_object_and_check(params = {})
28
- rubys3_client = Aws::S3::Client.new
29
- rubys3_client.put_object(params)
30
- # polls in a loop, sleeping between attempts
31
- rubys3_client.wait_until(:object_exists,
32
- {
33
- bucket: params[:bucket],
34
- key: params[:key]
35
- },
36
- {
37
- max_attempts: 30,
38
- delay: 0.1, # seconds
39
- }
40
- )
41
- end
42
-
43
- def self.list_files_before_time(bucket, prefix, time)
44
- rubys3_client = Aws::S3::Client.new
45
- oldest_list = []
46
- total_size = 0
47
-
48
- # Return nothing if bucket doesn't exist (it won't at the very beginning)
49
- begin
50
- rubys3_client.head_bucket(bucket: bucket)
51
- rescue Aws::S3::Errors::NotFound
52
- return total_size, oldest_list
53
- end
54
-
55
- # Get List of Packet Names - Assumes prefix gets us to a folder of packet names
56
- token = nil
57
- folder_list = []
58
- while true
59
- resp = rubys3_client.list_objects_v2({
60
- bucket: bucket,
61
- max_keys: 1000,
62
- prefix: prefix,
63
- delimiter: '/',
64
- continuation_token: token
65
- })
66
-
67
- resp.common_prefixes.each do |item|
68
- folder_list << item.prefix
69
- end
70
- break unless resp.is_truncated
71
- token = resp.next_continuation_token
72
- end
73
-
74
- # Go through each folder and keep files that end before time
75
- folder_list.each do |folder|
76
- token = nil
77
- next_folder = false
78
- while true
79
- resp = rubys3_client.list_objects_v2({
80
- bucket: bucket,
81
- max_keys: 1000,
82
- prefix: folder,
83
- continuation_token: token
84
- })
85
- resp.contents.each do |item|
86
- t = item.key.split('__')[1]
87
- file_end_time = Time.utc(t[0..3], t[4..5], t[6..7], t[8..9], t[10..11], t[12..13])
88
- if file_end_time < time
89
- oldest_list << item
90
- total_size += item.size
91
- else
92
- next_folder = true
93
- break
94
- end
95
- end
96
- break if !resp.is_truncated or next_folder
97
-
98
- token = resp.next_continuation_token
99
- end
100
- end
101
- return total_size, oldest_list
102
- end
103
-
104
- def self.get_total_size_and_oldest_list(bucket, prefix, max_list_length = 10000)
105
- rubys3_client = Aws::S3::Client.new
106
- oldest_list = []
107
- total_size = 0
108
-
109
- # Return nothing if bucket doesn't exist (it won't at the very beginning)
110
- begin
111
- rubys3_client.head_bucket(bucket: bucket)
112
- rescue Aws::S3::Errors::NotFound
113
- return total_size, oldest_list
114
- end
115
-
116
- # Get List of Files from S3
117
- token = nil
118
- while true
119
- resp = rubys3_client.list_objects_v2({
120
- bucket: bucket,
121
- max_keys: 1000,
122
- prefix: prefix,
123
- continuation_token: token
124
- })
125
- resp.contents.each do |item|
126
- total_size += item.size
127
- end
128
- oldest_list.concat(resp.contents)
129
- oldest_list.sort! { |a, b| File.basename(a.key) <=> File.basename(b.key) }
130
- oldest_list = oldest_list[0..(max_list_length - 1)]
131
- break unless resp.is_truncated
132
-
133
- token = resp.next_continuation_token
134
- end
135
- return total_size, oldest_list
136
- end
137
-
138
- def self.move_log_file_to_s3(filename, s3_key, metadata: {})
139
- Thread.new do
140
- rubys3_client = Aws::S3::Client.new
141
-
142
- # Ensure logs bucket exists
143
- begin
144
- rubys3_client.head_bucket(bucket: 'logs')
145
- rescue Aws::S3::Errors::NotFound
146
- rubys3_client.create_bucket(bucket: 'logs')
147
- end
148
-
149
- # Write to S3 Bucket
150
- File.open(filename, 'rb') do |read_file|
151
- rubys3_client.put_object(bucket: 'logs', key: s3_key, body: read_file, metadata: metadata)
152
- end
153
- Logger.debug "logs/#{s3_key} written to S3"
154
- ReducerModel.add_file(s3_key) # Record the new file for data reduction
155
-
156
- File.delete(filename)
157
- rescue => err
158
- Logger.error("Error saving log file to bucket: #{filename}\n#{err.formatted}")
159
- end
160
- end
161
-
162
- def self.ensure_public_bucket(bucket_name)
163
- rubys3_client = Aws::S3::Client.new
164
- begin
165
- rubys3_client.head_bucket(bucket: bucket_name)
166
- rescue Aws::S3::Errors::NotFound
167
- rubys3_client.create_bucket(bucket: bucket_name)
168
-
169
- policy = <<~EOL
170
- {
171
- "Version": "2012-10-17",
172
- "Statement": [
173
- {
174
- "Action": [
175
- "s3:GetBucketLocation",
176
- "s3:ListBucket"
177
- ],
178
- "Effect": "Allow",
179
- "Principal": {
180
- "AWS": [
181
- "*"
182
- ]
183
- },
184
- "Resource": [
185
- "arn:aws:s3:::#{bucket_name}"
186
- ],
187
- "Sid": ""
188
- },
189
- {
190
- "Action": [
191
- "s3:GetObject"
192
- ],
193
- "Effect": "Allow",
194
- "Principal": {
195
- "AWS": [
196
- "*"
197
- ]
198
- },
199
- "Resource": [
200
- "arn:aws:s3:::#{bucket_name}/*"
201
- ],
202
- "Sid": ""
203
- }
204
- ]
205
- }
206
- EOL
207
-
208
- rubys3_client.put_bucket_policy({ bucket: bucket_name, policy: policy })
209
- end
210
- end
211
-
212
- def self.get_cache_control(filename)
213
- # Allow caching for files that have a filename versioning strategy
214
- has_version_number = /(-|_|\.)\d+(-|_|\.)\d+(-|_|\.)\d+\./.match(@filename)
215
- has_content_hash = /\.[a-f0-9]{20}\./.match(@filename)
216
- return nil if has_version_number or has_content_hash
217
- return 'no-cache'
218
- end
219
- end
220
- end
@@ -1,274 +0,0 @@
1
- # encoding: ascii-8bit
2
-
3
- # Copyright 2022 Ball Aerospace & Technologies Corp.
4
- # All Rights Reserved.
5
- #
6
- # This program is free software; you can modify and/or redistribute it
7
- # under the terms of the GNU Affero General Public License
8
- # as published by the Free Software Foundation; version 3 with
9
- # attribution addendums as found in the LICENSE.txt
10
- #
11
- # This program is distributed in the hope that it will be useful,
12
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- # GNU Affero General Public License for more details.
15
-
16
- # Modified by OpenC3, Inc.
17
- # All changes Copyright 2022, OpenC3, Inc.
18
- # All Rights Reserved
19
-
20
- require 'fileutils'
21
- require 'tmpdir'
22
- require 'openc3'
23
- require 'openc3/utilities/s3'
24
-
25
- class S3File
26
- attr_reader :s3_path
27
- attr_reader :local_path
28
- attr_reader :reservation_count
29
- attr_reader :size
30
- attr_reader :error
31
- attr_accessor :priority
32
-
33
- def initialize(s3_path, size = 0, priority = 0)
34
- @rubys3_client = Aws::S3::Client.new
35
- begin
36
- @rubys3_client.head_bucket(bucket: 'logs')
37
- rescue Aws::S3::Errors::NotFound
38
- @rubys3_client.create_bucket(bucket: 'logs')
39
- end
40
-
41
- @s3_path = s3_path
42
- @local_path = nil
43
- @reservation_count = 0
44
- @size = size
45
- @priority = priority
46
- @error = nil
47
- @mutex = Mutex.new
48
- end
49
-
50
- def retrieve
51
- local_path = "#{S3FileCache.instance.cache_dir}/#{File.basename(@s3_path)}"
52
- OpenC3::Logger.debug "Retrieving #{@s3_path} from logs bucket"
53
- @rubys3_client.get_object(bucket: "logs", key: @s3_path, response_target: local_path)
54
- if File.exist?(local_path)
55
- @size = File.size(local_path)
56
- @local_path = local_path
57
- end
58
- rescue => err
59
- @error = err
60
- OpenC3::Logger.error "Failed to retrieve #{@s3_path}\n#{err.formatted}"
61
- raise err
62
- end
63
-
64
- def reserve
65
- @mutex.synchronize do
66
- @reservation_count += 1
67
- end
68
- end
69
-
70
- def unreserve
71
- @mutex.synchronize do
72
- @reservation_count -= 1
73
- delete() if @reservation_count <= 0
74
- end
75
- end
76
-
77
- # private
78
-
79
- def delete
80
- if @local_path and File.exist?(local_path)
81
- File.delete(@local_path)
82
- @local_path = nil
83
- end
84
- end
85
- end
86
-
87
- class S3FileCollection
88
- def initialize
89
- @array = []
90
- @mutex = Mutex.new
91
- end
92
-
93
- def add(s3_path, size, priority)
94
- @mutex.synchronize do
95
- @array.each do |file|
96
- if file.s3_path == s3_path
97
- file.priority = priority if priority < file.priority
98
- @array.sort! {|a,b| a.priority <=> b.priority}
99
- return file
100
- end
101
- end
102
- file = S3File.new(s3_path, size, priority)
103
- @array << file
104
- @array.sort! {|a,b| a.priority <=> b.priority}
105
- return file
106
- end
107
- end
108
-
109
- def length
110
- @array.length
111
- end
112
-
113
- def get(local_path)
114
- @mutex.synchronize do
115
- @array.each do |file|
116
- return file if file.local_path == local_path
117
- end
118
- end
119
- return nil
120
- end
121
-
122
- def get_next_to_retrieve
123
- @mutex.synchronize do
124
- @array.each do |file|
125
- return file unless file.local_path
126
- end
127
- end
128
- return nil
129
- end
130
-
131
- def current_disk_usage
132
- @mutex.synchronize do
133
- total_size = 0
134
- @array.each do |file|
135
- total_size += file.size if file.local_path
136
- end
137
- return total_size
138
- end
139
- end
140
- end
141
-
142
- class S3FileCache
143
- MAX_DISK_USAGE = 20_000_000_000 # 20 GB
144
- TIMESTAMP_FORMAT = "%Y%m%d%H%M%S%N" # TODO: get from different class?
145
-
146
- attr_reader :cache_dir
147
-
148
- @@instance = nil
149
- @@mutex = Mutex.new
150
-
151
- def self.instance
152
- return @@instance if @@instance
153
- @@mutex.synchronize do
154
- @@instance ||= S3FileCache.new
155
- end
156
- @@instance
157
- end
158
-
159
- def initialize(name = 'default', max_disk_usage = MAX_DISK_USAGE)
160
- @max_disk_usage = max_disk_usage
161
-
162
- @rubys3_client = Aws::S3::Client.new
163
- begin
164
- @rubys3_client.head_bucket(bucket: 'logs')
165
- rescue Aws::S3::Errors::NotFound
166
- @rubys3_client.create_bucket(bucket: 'logs')
167
- end
168
-
169
- # Create local file cache location
170
- @cache_dir = Dir.mktmpdir
171
- FileUtils.mkdir_p(@cache_dir)
172
- at_exit do
173
- FileUtils.remove_dir(@cache_dir, true)
174
- end
175
-
176
- @cached_files = S3FileCollection.new
177
-
178
- @thread = Thread.new do
179
- while true
180
- file = @cached_files.get_next_to_retrieve
181
- # OpenC3::Logger.debug "Next file: #{file}"
182
- if file and (file.size + @cached_files.current_disk_usage()) <= @max_disk_usage
183
- begin
184
- file.retrieve
185
- rescue
186
- # Will be automatically retried
187
- end
188
- else
189
- sleep(1)
190
- end
191
- end
192
- rescue => err
193
- OpenC3::Logger.error "S3FileCache thread unexpectedly died\n#{err.formatted}"
194
- end
195
- end
196
-
197
- def reserve_file(cmd_or_tlm, target_name, packet_name, start_time_nsec, end_time_nsec, type = :DECOM, timeout = 60, scope:)
198
- # OpenC3::Logger.debug "reserve_file #{cmd_or_tlm}:#{target_name}:#{packet_name} start:#{start_time_nsec / 1_000_000_000} end:#{end_time_nsec / 1_000_000_000} type:#{type} timeout:#{timeout}"
199
- # Get List of Files from S3
200
- total_resp = []
201
- token = nil
202
- dates = []
203
- cur_date = Time.at(start_time_nsec / Time::NSEC_PER_SECOND).beginning_of_day
204
- end_date = Time.at(end_time_nsec / Time::NSEC_PER_SECOND).beginning_of_day
205
- cur_date -= 1.day # start looking in the folder for the day before because log files can span across midnight
206
- while cur_date <= end_date
207
- dates << cur_date.strftime("%Y%m%d")
208
- cur_date += 1.day
209
- end
210
- prefixes = []
211
- dates.each do |date|
212
- while true
213
- prefixes << "#{scope}/#{type.to_s.downcase}_logs/#{cmd_or_tlm.to_s.downcase}/#{target_name}/#{packet_name}/#{date}"
214
- resp = @rubys3_client.list_objects_v2({
215
- bucket: "logs",
216
- max_keys: 1000,
217
- prefix: prefixes[-1],
218
- continuation_token: token
219
- })
220
- total_resp.concat(resp.contents)
221
- break unless resp.is_truncated
222
- token = resp.next_continuation_token
223
- end
224
- end
225
-
226
- # Add to needed files
227
- files = []
228
- total_resp.each_with_index do |item, index|
229
- s3_path = item.key
230
- if file_in_time_range(s3_path, start_time_nsec, end_time_nsec)
231
- file = @cached_files.add(s3_path, item.size, index)
232
- files << file
233
- end
234
- end
235
-
236
- # Wait for first file retrieval
237
- if files.length > 0
238
- wait_start = Time.now
239
- file = files[0]
240
- file.reserve
241
- while (Time.now - wait_start) < timeout
242
- return file.local_path if file.local_path
243
- sleep(1)
244
- end
245
- # Remove reservations if we timeout
246
- file.unreserve
247
- else
248
- OpenC3::Logger.info "No files found for #{prefixes}"
249
- end
250
-
251
- return nil
252
- end
253
-
254
- def unreserve_file(filename)
255
- @@mutex.synchronize do
256
- file = @cached_files.get(filename)
257
- file.unreserve if file
258
- end
259
- end
260
-
261
- # private
262
-
263
- def file_in_time_range(s3_path, start_time_nsec, end_time_nsec)
264
- basename = File.basename(s3_path)
265
- file_start_timestamp, file_end_timestamp, other = basename.split("__")
266
- file_start_time_nsec = DateTime.strptime(file_start_timestamp, TIMESTAMP_FORMAT).to_f * Time::NSEC_PER_SECOND
267
- file_end_time_nsec = DateTime.strptime(file_end_timestamp, TIMESTAMP_FORMAT).to_f * Time::NSEC_PER_SECOND
268
- if (start_time_nsec < file_end_time_nsec) and (end_time_nsec >= file_start_time_nsec)
269
- return true
270
- else
271
- return false
272
- end
273
- end
274
- end