openc3 5.0.6

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 (307) hide show
  1. checksums.yaml +7 -0
  2. data/Gemfile +18 -0
  3. data/Guardfile +35 -0
  4. data/LICENSE.txt +727 -0
  5. data/README.md +37 -0
  6. data/Rakefile +131 -0
  7. data/bin/cstol_converter +1178 -0
  8. data/bin/openc3cli +531 -0
  9. data/bin/rubysloc +139 -0
  10. data/data/config/_array_params.yaml +23 -0
  11. data/data/config/_id_items.yaml +24 -0
  12. data/data/config/_id_params.yaml +58 -0
  13. data/data/config/_interfaces.yaml +214 -0
  14. data/data/config/_interfaces.yaml.err +1017 -0
  15. data/data/config/_items.yaml +20 -0
  16. data/data/config/_params.yaml +60 -0
  17. data/data/config/cmd_tlm_server.yaml +136 -0
  18. data/data/config/command.yaml +44 -0
  19. data/data/config/command_modifiers.yaml +160 -0
  20. data/data/config/command_telemetry.yaml +3 -0
  21. data/data/config/interface_modifiers.yaml +104 -0
  22. data/data/config/item_modifiers.yaml +221 -0
  23. data/data/config/microservice.yaml +78 -0
  24. data/data/config/param_item_modifiers.yaml +52 -0
  25. data/data/config/parameter_modifiers.yaml +200 -0
  26. data/data/config/plugins.yaml +80 -0
  27. data/data/config/protocols.yaml +290 -0
  28. data/data/config/screen.yaml +147 -0
  29. data/data/config/table_manager.yaml +89 -0
  30. data/data/config/table_parameter_modifiers.yaml +9 -0
  31. data/data/config/target.yaml +142 -0
  32. data/data/config/target_config.yaml +94 -0
  33. data/data/config/telemetry.yaml +87 -0
  34. data/data/config/telemetry_modifiers.yaml +159 -0
  35. data/data/config/tool.yaml +63 -0
  36. data/data/config/unknown.yaml +3 -0
  37. data/data/config/widgets.yaml +1505 -0
  38. data/ext/mkrf_conf.rb +49 -0
  39. data/ext/openc3/ext/array/array.c +122 -0
  40. data/ext/openc3/ext/array/extconf.rb +13 -0
  41. data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
  42. data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
  43. data/ext/openc3/ext/config_parser/config_parser.c +280 -0
  44. data/ext/openc3/ext/config_parser/extconf.rb +13 -0
  45. data/ext/openc3/ext/crc/crc.c +351 -0
  46. data/ext/openc3/ext/crc/extconf.rb +13 -0
  47. data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
  48. data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
  49. data/ext/openc3/ext/packet/extconf.rb +13 -0
  50. data/ext/openc3/ext/packet/packet.c +318 -0
  51. data/ext/openc3/ext/platform/extconf.rb +13 -0
  52. data/ext/openc3/ext/platform/platform.c +134 -0
  53. data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
  54. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
  55. data/ext/openc3/ext/string/extconf.rb +13 -0
  56. data/ext/openc3/ext/string/string.c +63 -0
  57. data/ext/openc3/ext/structure/structure.c +1719 -0
  58. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
  59. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
  60. data/ext/openc3/ext/telemetry/extconf.rb +13 -0
  61. data/ext/openc3/ext/telemetry/telemetry.c +336 -0
  62. data/lib/cosmos.rb +20 -0
  63. data/lib/cosmosc2.rb +20 -0
  64. data/lib/openc3/api/api.rb +39 -0
  65. data/lib/openc3/api/authorized_api.rb +30 -0
  66. data/lib/openc3/api/cmd_api.rb +451 -0
  67. data/lib/openc3/api/config_api.rb +58 -0
  68. data/lib/openc3/api/interface_api.rb +117 -0
  69. data/lib/openc3/api/limits_api.rb +375 -0
  70. data/lib/openc3/api/router_api.rb +117 -0
  71. data/lib/openc3/api/settings_api.rb +70 -0
  72. data/lib/openc3/api/target_api.rb +78 -0
  73. data/lib/openc3/api/tlm_api.rb +455 -0
  74. data/lib/openc3/bridge/bridge.rb +54 -0
  75. data/lib/openc3/bridge/bridge_config.rb +167 -0
  76. data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
  77. data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
  78. data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
  79. data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
  80. data/lib/openc3/config/config_parser.rb +549 -0
  81. data/lib/openc3/config/meta_config_parser.rb +74 -0
  82. data/lib/openc3/conversions/conversion.rb +70 -0
  83. data/lib/openc3/conversions/generic_conversion.rb +83 -0
  84. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
  85. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
  86. data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
  87. data/lib/openc3/conversions/processor_conversion.rb +70 -0
  88. data/lib/openc3/conversions/received_count_conversion.rb +38 -0
  89. data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
  90. data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
  91. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
  92. data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
  93. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
  94. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
  95. data/lib/openc3/conversions.rb +34 -0
  96. data/lib/openc3/core_ext/array.rb +416 -0
  97. data/lib/openc3/core_ext/binding.rb +29 -0
  98. data/lib/openc3/core_ext/class.rb +72 -0
  99. data/lib/openc3/core_ext/exception.rb +61 -0
  100. data/lib/openc3/core_ext/file.rb +83 -0
  101. data/lib/openc3/core_ext/hash.rb +37 -0
  102. data/lib/openc3/core_ext/io.rb +134 -0
  103. data/lib/openc3/core_ext/kernel.rb +42 -0
  104. data/lib/openc3/core_ext/math.rb +128 -0
  105. data/lib/openc3/core_ext/matrix.rb +156 -0
  106. data/lib/openc3/core_ext/objectspace.rb +36 -0
  107. data/lib/openc3/core_ext/openc3_io.rb +57 -0
  108. data/lib/openc3/core_ext/range.rb +27 -0
  109. data/lib/openc3/core_ext/socket.rb +38 -0
  110. data/lib/openc3/core_ext/string.rb +389 -0
  111. data/lib/openc3/core_ext/stringio.rb +33 -0
  112. data/lib/openc3/core_ext/time.rb +508 -0
  113. data/lib/openc3/core_ext.rb +36 -0
  114. data/lib/openc3/interfaces/interface.rb +498 -0
  115. data/lib/openc3/interfaces/linc_interface.rb +475 -0
  116. data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
  117. data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
  118. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
  119. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
  120. data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
  121. data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
  122. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
  123. data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
  124. data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
  125. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
  126. data/lib/openc3/interfaces/serial_interface.rb +94 -0
  127. data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
  128. data/lib/openc3/interfaces/stream_interface.rb +81 -0
  129. data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
  130. data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
  131. data/lib/openc3/interfaces/udp_interface.rb +169 -0
  132. data/lib/openc3/interfaces.rb +44 -0
  133. data/lib/openc3/io/buffered_file.rb +109 -0
  134. data/lib/openc3/io/io_multiplexer.rb +80 -0
  135. data/lib/openc3/io/json_api_object.rb +208 -0
  136. data/lib/openc3/io/json_drb.rb +335 -0
  137. data/lib/openc3/io/json_drb_object.rb +114 -0
  138. data/lib/openc3/io/json_drb_rack.rb +84 -0
  139. data/lib/openc3/io/json_rpc.rb +420 -0
  140. data/lib/openc3/io/openc3_snmp.rb +58 -0
  141. data/lib/openc3/io/posix_serial_driver.rb +156 -0
  142. data/lib/openc3/io/raw_logger.rb +167 -0
  143. data/lib/openc3/io/raw_logger_pair.rb +77 -0
  144. data/lib/openc3/io/serial_driver.rb +105 -0
  145. data/lib/openc3/io/stderr.rb +43 -0
  146. data/lib/openc3/io/stdout.rb +43 -0
  147. data/lib/openc3/io/udp_sockets.rb +194 -0
  148. data/lib/openc3/io/win32_serial_driver.rb +196 -0
  149. data/lib/openc3/logs/log_writer.rb +302 -0
  150. data/lib/openc3/logs/packet_log_constants.rb +62 -0
  151. data/lib/openc3/logs/packet_log_reader.rb +345 -0
  152. data/lib/openc3/logs/packet_log_writer.rb +299 -0
  153. data/lib/openc3/logs/text_log_writer.rb +68 -0
  154. data/lib/openc3/logs.rb +25 -0
  155. data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
  156. data/lib/openc3/microservices/decom_microservice.rb +136 -0
  157. data/lib/openc3/microservices/interface_microservice.rb +532 -0
  158. data/lib/openc3/microservices/log_microservice.rb +108 -0
  159. data/lib/openc3/microservices/microservice.rb +204 -0
  160. data/lib/openc3/microservices/plugin_microservice.rb +43 -0
  161. data/lib/openc3/microservices/reaction_microservice.rb +541 -0
  162. data/lib/openc3/microservices/reducer_microservice.rb +313 -0
  163. data/lib/openc3/microservices/router_microservice.rb +44 -0
  164. data/lib/openc3/microservices/text_log_microservice.rb +84 -0
  165. data/lib/openc3/microservices/timeline_microservice.rb +363 -0
  166. data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
  167. data/lib/openc3/models/activity_model.rb +319 -0
  168. data/lib/openc3/models/auth_model.rb +65 -0
  169. data/lib/openc3/models/cvt_model.rb +185 -0
  170. data/lib/openc3/models/environment_model.rb +58 -0
  171. data/lib/openc3/models/gem_model.rb +137 -0
  172. data/lib/openc3/models/info_model.rb +31 -0
  173. data/lib/openc3/models/interface_model.rb +281 -0
  174. data/lib/openc3/models/interface_status_model.rb +117 -0
  175. data/lib/openc3/models/metadata_model.rb +139 -0
  176. data/lib/openc3/models/metric_model.rb +59 -0
  177. data/lib/openc3/models/microservice_model.rb +206 -0
  178. data/lib/openc3/models/microservice_status_model.rb +74 -0
  179. data/lib/openc3/models/model.rb +204 -0
  180. data/lib/openc3/models/note_model.rb +122 -0
  181. data/lib/openc3/models/notification_model.rb +40 -0
  182. data/lib/openc3/models/ping_model.rb +35 -0
  183. data/lib/openc3/models/plugin_model.rb +292 -0
  184. data/lib/openc3/models/process_status_model.rb +76 -0
  185. data/lib/openc3/models/reaction_model.rb +322 -0
  186. data/lib/openc3/models/reducer_model.rb +65 -0
  187. data/lib/openc3/models/router_model.rb +35 -0
  188. data/lib/openc3/models/router_status_model.rb +27 -0
  189. data/lib/openc3/models/scope_model.rb +153 -0
  190. data/lib/openc3/models/settings_model.rb +55 -0
  191. data/lib/openc3/models/sorted_model.rb +167 -0
  192. data/lib/openc3/models/target_model.rb +759 -0
  193. data/lib/openc3/models/timeline_model.rb +154 -0
  194. data/lib/openc3/models/tool_config_model.rb +38 -0
  195. data/lib/openc3/models/tool_model.rb +262 -0
  196. data/lib/openc3/models/trigger_group_model.rb +186 -0
  197. data/lib/openc3/models/trigger_model.rb +330 -0
  198. data/lib/openc3/models/widget_model.rb +138 -0
  199. data/lib/openc3/operators/microservice_operator.rb +128 -0
  200. data/lib/openc3/operators/operator.rb +277 -0
  201. data/lib/openc3/packets/binary_accessor.rb +1207 -0
  202. data/lib/openc3/packets/commands.rb +373 -0
  203. data/lib/openc3/packets/json_packet.rb +134 -0
  204. data/lib/openc3/packets/limits.rb +271 -0
  205. data/lib/openc3/packets/limits_response.rb +53 -0
  206. data/lib/openc3/packets/packet.rb +1168 -0
  207. data/lib/openc3/packets/packet_config.rb +625 -0
  208. data/lib/openc3/packets/packet_item.rb +586 -0
  209. data/lib/openc3/packets/packet_item_limits.rb +162 -0
  210. data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
  211. data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
  212. data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
  213. data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
  214. data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
  215. data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
  216. data/lib/openc3/packets/parsers/state_parser.rb +127 -0
  217. data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
  218. data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
  219. data/lib/openc3/packets/structure.rb +553 -0
  220. data/lib/openc3/packets/structure_item.rb +365 -0
  221. data/lib/openc3/packets/telemetry.rb +487 -0
  222. data/lib/openc3/processors/processor.rb +86 -0
  223. data/lib/openc3/processors/statistics_processor.rb +82 -0
  224. data/lib/openc3/processors/watermark_processor.rb +58 -0
  225. data/lib/openc3/processors.rb +24 -0
  226. data/lib/openc3/script/api_shared.rb +828 -0
  227. data/lib/openc3/script/calendar.rb +89 -0
  228. data/lib/openc3/script/commands.rb +227 -0
  229. data/lib/openc3/script/exceptions.rb +29 -0
  230. data/lib/openc3/script/extract.rb +161 -0
  231. data/lib/openc3/script/limits.rb +60 -0
  232. data/lib/openc3/script/script.rb +299 -0
  233. data/lib/openc3/script/script_runner.rb +238 -0
  234. data/lib/openc3/script/storage.rb +146 -0
  235. data/lib/openc3/script/suite.rb +542 -0
  236. data/lib/openc3/script/suite_results.rb +196 -0
  237. data/lib/openc3/script/suite_runner.rb +217 -0
  238. data/lib/openc3/script.rb +21 -0
  239. data/lib/openc3/streams/serial_stream.rb +167 -0
  240. data/lib/openc3/streams/stream.rb +63 -0
  241. data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
  242. data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
  243. data/lib/openc3/system/system.rb +127 -0
  244. data/lib/openc3/system/system_config.rb +411 -0
  245. data/lib/openc3/system/target.rb +269 -0
  246. data/lib/openc3/system.rb +24 -0
  247. data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
  248. data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
  249. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
  250. data/lib/openc3/tools/table_manager/table.rb +77 -0
  251. data/lib/openc3/tools/table_manager/table_config.rb +273 -0
  252. data/lib/openc3/tools/table_manager/table_item.rb +90 -0
  253. data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
  254. data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
  255. data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
  256. data/lib/openc3/tools/test_runner/test.rb +67 -0
  257. data/lib/openc3/top_level.rb +595 -0
  258. data/lib/openc3/topics/autonomic_topic.rb +52 -0
  259. data/lib/openc3/topics/calendar_topic.rb +44 -0
  260. data/lib/openc3/topics/command_decom_topic.rb +76 -0
  261. data/lib/openc3/topics/command_topic.rb +83 -0
  262. data/lib/openc3/topics/config_topic.rb +68 -0
  263. data/lib/openc3/topics/interface_topic.rb +73 -0
  264. data/lib/openc3/topics/limits_event_topic.rb +109 -0
  265. data/lib/openc3/topics/notifications_topic.rb +28 -0
  266. data/lib/openc3/topics/router_topic.rb +85 -0
  267. data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
  268. data/lib/openc3/topics/telemetry_topic.rb +36 -0
  269. data/lib/openc3/topics/timeline_topic.rb +45 -0
  270. data/lib/openc3/topics/topic.rb +53 -0
  271. data/lib/openc3/utilities/authentication.rb +141 -0
  272. data/lib/openc3/utilities/authorization.rb +51 -0
  273. data/lib/openc3/utilities/crc.rb +278 -0
  274. data/lib/openc3/utilities/csv.rb +153 -0
  275. data/lib/openc3/utilities/logger.rb +187 -0
  276. data/lib/openc3/utilities/message_log.rb +91 -0
  277. data/lib/openc3/utilities/metric.rb +141 -0
  278. data/lib/openc3/utilities/process_manager.rb +139 -0
  279. data/lib/openc3/utilities/quaternion.rb +257 -0
  280. data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
  281. data/lib/openc3/utilities/s3.rb +202 -0
  282. data/lib/openc3/utilities/s3_autoload.rb +9 -0
  283. data/lib/openc3/utilities/s3_file_cache.rb +274 -0
  284. data/lib/openc3/utilities/simulated_target.rb +117 -0
  285. data/lib/openc3/utilities/sleeper.rb +51 -0
  286. data/lib/openc3/utilities/store.rb +23 -0
  287. data/lib/openc3/utilities/store_autoload.rb +237 -0
  288. data/lib/openc3/utilities/zip.rb +21 -0
  289. data/lib/openc3/utilities.rb +35 -0
  290. data/lib/openc3/version.rb +14 -0
  291. data/lib/openc3/win32/excel.rb +132 -0
  292. data/lib/openc3/win32/win32.rb +402 -0
  293. data/lib/openc3/win32/win32_main.rb +333 -0
  294. data/lib/openc3.rb +49 -0
  295. data/tasks/gemfile_stats.rake +113 -0
  296. data/tasks/spec.rake +30 -0
  297. data/templates/plugin-template/README.md +15 -0
  298. data/templates/plugin-template/Rakefile +12 -0
  299. data/templates/plugin-template/plugin.gemspec +23 -0
  300. data/templates/plugin-template/plugin.txt +9 -0
  301. data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
  302. data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
  303. data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
  304. data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
  305. data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
  306. data/templates/plugin-template/targets/TARGET/target.txt +5 -0
  307. metadata +849 -0
@@ -0,0 +1,759 @@
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 'openc3/top_level'
21
+ require 'openc3/models/model'
22
+ require 'openc3/models/cvt_model'
23
+ require 'openc3/models/microservice_model'
24
+ require 'openc3/topics/limits_event_topic'
25
+ require 'openc3/topics/config_topic'
26
+ require 'openc3/system'
27
+ require 'openc3/utilities/s3'
28
+ require 'openc3/utilities/zip'
29
+ require 'fileutils'
30
+ require 'tmpdir'
31
+
32
+ module OpenC3
33
+ # Manages the target in Redis. It stores the target itself under the
34
+ # <SCOPE>__openc3_targets key under the target name field. All the command packets
35
+ # in the target are stored under the <SCOPE>__openc3cmd__<TARGET NAME> key and the
36
+ # telemetry under the <SCOPE>__openc3tlm__<TARGET NAME> key. Any new limits sets
37
+ # are merged into the <SCOPE>__limits_sets key as fields. Any new limits groups are
38
+ # created under <SCOPE>__limits_groups with field name. These Redis key/fields are
39
+ # all removed when the undeploy method is called.
40
+ class TargetModel < Model
41
+ PRIMARY_KEY = 'openc3_targets'
42
+ VALID_TYPES = %i(CMD TLM)
43
+
44
+ attr_accessor :folder_name
45
+ attr_accessor :requires
46
+ attr_accessor :ignored_parameters
47
+ attr_accessor :ignored_items
48
+ attr_accessor :limits_groups
49
+ attr_accessor :cmd_tlm_files
50
+ attr_accessor :cmd_unique_id_mode
51
+ attr_accessor :tlm_unique_id_mode
52
+ attr_accessor :id
53
+ attr_accessor :cmd_log_cycle_time
54
+ attr_accessor :cmd_log_cycle_size
55
+ attr_accessor :cmd_log_retain_time
56
+ attr_accessor :cmd_decom_log_cycle_time
57
+ attr_accessor :cmd_decom_log_cycle_size
58
+ attr_accessor :cmd_decom_log_retain_time
59
+ attr_accessor :tlm_log_cycle_time
60
+ attr_accessor :tlm_log_cycle_size
61
+ attr_accessor :tlm_log_retain_time
62
+ attr_accessor :tlm_decom_log_cycle_time
63
+ attr_accessor :tlm_decom_log_cycle_size
64
+ attr_accessor :tlm_decom_log_retain_time
65
+ attr_accessor :reduced_minute_log_retain_time
66
+ attr_accessor :reduced_hour_log_retain_time
67
+ attr_accessor :reduced_day_log_retain_time
68
+ attr_accessor :cleanup_poll_time
69
+ attr_accessor :needs_dependencies
70
+
71
+ # NOTE: The following three class methods are used by the ModelController
72
+ # and are reimplemented to enable various Model class methods to work
73
+ def self.get(name:, scope:)
74
+ super("#{scope}__#{PRIMARY_KEY}", name: name)
75
+ end
76
+
77
+ def self.names(scope:)
78
+ super("#{scope}__#{PRIMARY_KEY}")
79
+ end
80
+
81
+ def self.all(scope:)
82
+ super("#{scope}__#{PRIMARY_KEY}")
83
+ end
84
+
85
+ # @return [Array] Array of all the packet names
86
+ def self.packet_names(target_name, type: :TLM, scope:)
87
+ raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
88
+ # If the key doesn't exist or if there are no packets we return empty array
89
+ Store.hkeys("#{scope}__openc3#{type.to_s.downcase}__#{target_name}").sort
90
+ end
91
+
92
+ # @return [Hash] Packet hash or raises an exception
93
+ def self.packet(target_name, packet_name, type: :TLM, scope:)
94
+ raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
95
+
96
+ # Assume it exists and just try to get it to avoid an extra call to Store.exist?
97
+ json = Store.hget("#{scope}__openc3#{type.to_s.downcase}__#{target_name}", packet_name)
98
+ raise "Packet '#{target_name} #{packet_name}' does not exist" if json.nil?
99
+
100
+ JSON.parse(json, :allow_nan => true, :create_additions => true)
101
+ end
102
+
103
+ # @return [Array>Hash>] All packet hashes under the target_name
104
+ def self.packets(target_name, type: :TLM, scope:)
105
+ raise "Unknown type #{type} for #{target_name}" unless VALID_TYPES.include?(type)
106
+ raise "Target '#{target_name}' does not exist" unless get(name: target_name, scope: scope)
107
+
108
+ result = []
109
+ packets = Store.hgetall("#{scope}__openc3#{type.to_s.downcase}__#{target_name}")
110
+ packets.sort.each do |packet_name, packet_json|
111
+ result << JSON.parse(packet_json, :allow_nan => true, :create_additions => true)
112
+ end
113
+ result
114
+ end
115
+
116
+ # @return [Array>Hash>] All packet hashes under the target_name
117
+ def self.all_packet_name_descriptions(target_name, type: :TLM, scope:)
118
+ self.packets(target_name, type: type, scope: scope).map! { |hash| hash.slice("packet_name", "description") }
119
+ end
120
+
121
+ def self.set_packet(target_name, packet_name, packet, type: :TLM, scope:)
122
+ raise "Unknown type #{type} for #{target_name} #{packet_name}" unless VALID_TYPES.include?(type)
123
+
124
+ begin
125
+ Store.hset("#{scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
126
+ rescue JSON::GeneratorError => err
127
+ Logger.error("Invalid text present in #{target_name} #{packet_name} #{type.to_s.downcase} packet")
128
+ raise err
129
+ end
130
+ end
131
+
132
+ # @return [Hash] Item hash or raises an exception
133
+ def self.packet_item(target_name, packet_name, item_name, type: :TLM, scope:)
134
+ packet = packet(target_name, packet_name, type: type, scope: scope)
135
+ item = packet['items'].find { |item| item['name'] == item_name.to_s }
136
+ raise "Item '#{packet['target_name']} #{packet['packet_name']} #{item_name}' does not exist" unless item
137
+ item
138
+ end
139
+
140
+ # @return [Array<Hash>] Item hash array or raises an exception
141
+ def self.packet_items(target_name, packet_name, items, type: :TLM, scope:)
142
+ packet = packet(target_name, packet_name, type: type, scope: scope)
143
+ found = packet['items'].find_all { |item| items.map(&:to_s).include?(item['name']) }
144
+ if found.length != items.length # we didn't find them all
145
+ found_items = found.collect { |item| item['name'] }
146
+ not_found = []
147
+ (items - found_items).each do |item|
148
+ not_found << "'#{target_name} #{packet_name} #{item}'"
149
+ end
150
+ # 'does not exist' not gramatically correct but we use it in every other exception
151
+ raise "Item(s) #{not_found.join(', ')} does not exist"
152
+ end
153
+ found
154
+ end
155
+
156
+ # @return [Hash{String => Array<Array<String, String, String>>}]
157
+ def self.limits_groups(scope:)
158
+ groups = Store.hgetall("#{scope}__limits_groups")
159
+ if groups
160
+ groups.map { |group, items| [group, JSON.parse(items, :allow_nan => true, :create_additions => true)] }.to_h
161
+ else
162
+ {}
163
+ end
164
+ end
165
+
166
+ # Called by the PluginModel to allow this class to validate it's top-level keyword: "TARGET"
167
+ def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
168
+ case keyword
169
+ when 'TARGET'
170
+ usage = "#{keyword} <TARGET FOLDER NAME> <TARGET NAME>"
171
+ parser.verify_num_parameters(2, 2, usage)
172
+ parser.verify_parameter_naming(2) # Target name is the 2nd parameter
173
+ return self.new(name: parameters[1].to_s.upcase, folder_name: parameters[0].to_s.upcase, plugin: plugin, needs_dependencies: needs_dependencies, scope: scope)
174
+ else
175
+ raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Target: #{keyword} #{parameters.join(" ")}")
176
+ end
177
+ end
178
+
179
+ def initialize(
180
+ name:,
181
+ folder_name: nil,
182
+ requires: [],
183
+ ignored_parameters: [],
184
+ ignored_items: [],
185
+ limits_groups: [],
186
+ cmd_tlm_files: [],
187
+ cmd_unique_id_mode: false,
188
+ tlm_unique_id_mode: false,
189
+ id: nil,
190
+ updated_at: nil,
191
+ plugin: nil,
192
+ cmd_log_cycle_time: 600,
193
+ cmd_log_cycle_size: 50_000_000,
194
+ cmd_log_retain_time: nil,
195
+ cmd_decom_log_cycle_time: 600,
196
+ cmd_decom_log_cycle_size: 50_000_000,
197
+ cmd_decom_log_retain_time: nil,
198
+ tlm_log_cycle_time: 600,
199
+ tlm_log_cycle_size: 50_000_000,
200
+ tlm_log_retain_time: nil,
201
+ tlm_decom_log_cycle_time: 600,
202
+ tlm_decom_log_cycle_size: 50_000_000,
203
+ tlm_decom_log_retain_time: nil,
204
+ reduced_minute_log_retain_time: nil,
205
+ reduced_hour_log_retain_time: nil,
206
+ reduced_day_log_retain_time: nil,
207
+ cleanup_poll_time: 900,
208
+ needs_dependencies: false,
209
+ scope:
210
+ )
211
+ super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at,
212
+ cmd_log_cycle_time: cmd_log_cycle_time, cmd_log_cycle_size: cmd_log_cycle_size,
213
+ cmd_log_retain_time: cmd_log_retain_time,
214
+ cmd_decom_log_cycle_time: cmd_decom_log_cycle_time, cmd_decom_log_cycle_size: cmd_decom_log_cycle_size,
215
+ cmd_decom_log_retain_time: cmd_decom_log_retain_time,
216
+ tlm_log_cycle_time: tlm_log_cycle_time, tlm_log_cycle_size: tlm_log_cycle_size,
217
+ tlm_log_retain_time: tlm_log_retain_time,
218
+ tlm_decom_log_cycle_time: tlm_decom_log_cycle_time, tlm_decom_log_cycle_size: tlm_decom_log_cycle_size,
219
+ tlm_decom_log_retain_time: tlm_decom_log_retain_time,
220
+ reduced_minute_log_retain_time: reduced_minute_log_retain_time,
221
+ reduced_hour_log_retain_time: reduced_hour_log_retain_time, reduced_day_log_retain_time: reduced_day_log_retain_time,
222
+ cleanup_poll_time: cleanup_poll_time, needs_dependencies: needs_dependencies,
223
+ scope: scope)
224
+ @folder_name = folder_name
225
+ @requires = requires
226
+ @ignored_parameters = ignored_parameters
227
+ @ignored_items = ignored_items
228
+ @limits_groups = limits_groups
229
+ @cmd_tlm_files = cmd_tlm_files
230
+ @cmd_unique_id_mode = cmd_unique_id_mode
231
+ @tlm_unique_id_mode = tlm_unique_id_mode
232
+ @id = id
233
+ @cmd_log_cycle_time = cmd_log_cycle_time
234
+ @cmd_log_cycle_size = cmd_log_cycle_size
235
+ @cmd_log_retain_time = cmd_log_retain_time
236
+ @cmd_decom_log_cycle_time = cmd_decom_log_cycle_time
237
+ @cmd_decom_log_cycle_size = cmd_decom_log_cycle_size
238
+ @cmd_decom_log_retain_time = cmd_decom_log_retain_time
239
+ @tlm_log_cycle_time = tlm_log_cycle_time
240
+ @tlm_log_cycle_size = tlm_log_cycle_size
241
+ @tlm_log_retain_time = tlm_log_retain_time
242
+ @tlm_decom_log_cycle_time = tlm_decom_log_cycle_time
243
+ @tlm_decom_log_cycle_size = tlm_decom_log_cycle_size
244
+ @tlm_decom_log_retain_time = tlm_decom_log_retain_time
245
+ @reduced_minute_log_retain_time = reduced_minute_log_retain_time
246
+ @reduced_hour_log_retain_time = reduced_hour_log_retain_time
247
+ @reduced_day_log_retain_time = reduced_day_log_retain_time
248
+ @cleanup_poll_time = cleanup_poll_time
249
+ @needs_dependencies = needs_dependencies
250
+ end
251
+
252
+ def as_json(*a)
253
+ {
254
+ 'name' => @name,
255
+ 'folder_name' => @folder_name,
256
+ 'requires' => @requires,
257
+ 'ignored_parameters' => @ignored_parameters,
258
+ 'ignored_items' => @ignored_items,
259
+ 'limits_groups' => @limits_groups,
260
+ 'cmd_tlm_files' => @cmd_tlm_files,
261
+ 'cmd_unique_id_mode' => cmd_unique_id_mode,
262
+ 'tlm_unique_id_mode' => @tlm_unique_id_mode,
263
+ 'id' => @id,
264
+ 'updated_at' => @updated_at,
265
+ 'plugin' => @plugin,
266
+ 'cmd_log_cycle_time' => @cmd_log_cycle_time,
267
+ 'cmd_log_cycle_size' => @cmd_log_cycle_size,
268
+ 'cmd_log_retain_time' => @cmd_log_retain_time,
269
+ 'cmd_decom_log_cycle_time' => @cmd_decom_log_cycle_time,
270
+ 'cmd_decom_log_cycle_size' => @cmd_decom_log_cycle_size,
271
+ 'cmd_decom_log_retain_time' => @cmd_decom_log_retain_time,
272
+ 'tlm_log_cycle_time' => @tlm_log_cycle_time,
273
+ 'tlm_log_cycle_size' => @tlm_log_cycle_size,
274
+ 'tlm_log_retain_time' => @tlm_log_retain_time,
275
+ 'tlm_decom_log_cycle_time' => @tlm_decom_log_cycle_time,
276
+ 'tlm_decom_log_cycle_size' => @tlm_decom_log_cycle_size,
277
+ 'tlm_decom_log_retain_time' => @tlm_decom_log_retain_time,
278
+ 'reduced_minute_log_retain_time' => @reduced_minute_log_retain_time,
279
+ 'reduced_hour_log_retain_time' => @reduced_hour_log_retain_time,
280
+ 'reduced_day_log_retain_time' => @reduced_day_log_retain_time,
281
+ 'cleanup_poll_time' => @cleanup_poll_time,
282
+ 'needs_dependencies' => @needs_dependencies,
283
+ }
284
+ end
285
+
286
+ def as_config
287
+ "TARGET #{@folder_name} #{@name}\n"
288
+ end
289
+
290
+ # Handles Target specific configuration keywords
291
+ def handle_config(parser, keyword, parameters)
292
+ case keyword
293
+ when 'CMD_LOG_CYCLE_TIME'
294
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
295
+ @cmd_log_cycle_time = parameters[0].to_i
296
+ when 'CMD_LOG_CYCLE_SIZE'
297
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
298
+ @cmd_log_cycle_size = parameters[0].to_i
299
+ when 'CMD_LOG_RETAIN_TIME'
300
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd log files in seconds - nil = Forever>")
301
+ @cmd_log_retain_time = ConfigParser.handle_nil(parameters[0])
302
+ @cmd_log_retain_time = @cmd_log_retain_time.to_i if @cmd_log_retain_time
303
+ when 'CMD_DECOM_LOG_CYCLE_TIME'
304
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
305
+ @cmd_decom_log_cycle_time = parameters[0].to_i
306
+ when 'CMD_DECOM_LOG_CYCLE_SIZE'
307
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
308
+ @cmd_decom_log_cycle_size = parameters[0].to_i
309
+ when 'CMD_DECOM_LOG_RETAIN_TIME'
310
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for cmd decom log files in seconds - nil = Forever>")
311
+ @cmd_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
312
+ @cmd_decom_log_retain_time = @cmd_decom_log_retain_time.to_i if @cmd_decom_log_retain_time
313
+ when 'TLM_LOG_CYCLE_TIME'
314
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
315
+ @tlm_log_cycle_time = parameters[0].to_i
316
+ when 'TLM_LOG_CYCLE_SIZE'
317
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
318
+ @tlm_log_cycle_size = parameters[0].to_i
319
+ when 'TLM_LOG_RETAIN_TIME'
320
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm log files in seconds - nil = Forever>")
321
+ @tlm_log_retain_time = ConfigParser.handle_nil(parameters[0])
322
+ @tlm_log_retain_time = @tlm_log_retain_time.to_i if @tlm_log_retain_time
323
+ when 'TLM_DECOM_LOG_CYCLE_TIME'
324
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum time between files in seconds>")
325
+ @tlm_decom_log_cycle_time = parameters[0].to_i
326
+ when 'TLM_DECOM_LOG_CYCLE_SIZE'
327
+ parser.verify_num_parameters(1, 1, "#{keyword} <Maximum file size in bytes>")
328
+ @tlm_decom_log_cycle_size = parameters[0].to_i
329
+ when 'TLM_DECOM_LOG_RETAIN_TIME'
330
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for tlm decom log files in seconds - nil = Forever>")
331
+ @tlm_decom_log_retain_time = ConfigParser.handle_nil(parameters[0])
332
+ @tlm_decom_log_retain_time = @tlm_decom_log_retain_time.to_i if @tlm_decom_log_retain_time
333
+ when 'REDUCED_MINUTE_LOG_RETAIN_TIME'
334
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced minute log files in seconds - nil = Forever>")
335
+ @reduced_minute_log_retain_time = ConfigParser.handle_nil(parameters[0])
336
+ @reduced_minute_log_retain_time = @reduced_minute_log_retain_time.to_i if @reduced_minute_log_retain_time
337
+ when 'REDUCED_HOUR_LOG_RETAIN_TIME'
338
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced hour log files in seconds - nil = Forever>")
339
+ @reduced_hour_log_retain_time = ConfigParser.handle_nil(parameters[0])
340
+ @reduced_hour_log_retain_time = @reduced_hour_log_retain_time.to_i if @reduced_hour_log_retain_time
341
+ when 'REDUCED_DAY_LOG_RETAIN_TIME'
342
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for reduced day log files in seconds - nil = Forever>")
343
+ @reduced_day_log_retain_time = ConfigParser.handle_nil(parameters[0])
344
+ @reduced_day_log_retain_time = @reduced_day_log_retain_time.to_i if @reduced_day_log_retain_time
345
+ when 'LOG_RETAIN_TIME'
346
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all log files in seconds - nil = Forever>")
347
+ log_retain_time = ConfigParser.handle_nil(parameters[0])
348
+ if log_retain_time
349
+ @cmd_log_retain_time = log_retain_time.to_i
350
+ @cmd_decom_log_retain_time = log_retain_time.to_i
351
+ @tlm_log_retain_time = log_retain_time.to_i
352
+ @tlm_decom_log_retain_time = log_retain_time.to_i
353
+ end
354
+ when 'REDUCED_LOG_RETAIN_TIME'
355
+ parser.verify_num_parameters(1, 1, "#{keyword} <Retention time for all reduced log files in seconds - nil = Forever>")
356
+ reduced_log_retain_time = ConfigParser.handle_nil(parameters[0])
357
+ if reduced_log_retain_time
358
+ @reduced_minute_log_retain_time = reduced_log_retain_time.to_i
359
+ @reduced_hour_log_retain_time = reduced_log_retain_time.to_i
360
+ @reduced_day_log_retain_time = reduced_log_retain_time.to_i
361
+ end
362
+ when 'CLEANUP_POLL_TIME'
363
+ parser.verify_num_parameters(1, 1, "#{keyword} <Cleanup polling period in seconds>")
364
+ @cleanup_poll_time = parameters[0].to_i
365
+ else
366
+ raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Target: #{keyword} #{parameters.join(" ")}")
367
+ end
368
+ return nil
369
+ end
370
+
371
+ def deploy(gem_path, variables, validate_only: false)
372
+ rubys3_client = Aws::S3::Client.new
373
+ variables["target_name"] = @name
374
+ start_path = "/targets/#{@folder_name}/"
375
+ temp_dir = Dir.mktmpdir
376
+ found = false
377
+ begin
378
+ target_path = gem_path + start_path + "**/*"
379
+ Dir.glob(target_path) do |filename|
380
+ next if filename == '.' or filename == '..' or File.directory?(filename)
381
+
382
+ path = filename.split(gem_path)[-1]
383
+ target_folder_path = path.split(start_path)[-1]
384
+ key = "#{@scope}/targets/#{@name}/#{target_folder_path}"
385
+
386
+ # Load target files
387
+ @filename = filename # For render
388
+ data = File.read(filename, mode: "rb")
389
+ begin
390
+ OpenC3.set_working_dir(File.dirname(filename)) do
391
+ data = ERB.new(data, trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable? and File.basename(filename)[0] != '_'
392
+ end
393
+ rescue => error
394
+ raise "ERB error parsing: #{filename}: #{error.formatted}"
395
+ end
396
+ local_path = File.join(temp_dir, @name, target_folder_path)
397
+ FileUtils.mkdir_p(File.dirname(local_path))
398
+ File.open(local_path, 'wb') { |file| file.write(data) }
399
+ found = true
400
+ rubys3_client.put_object(bucket: 'config', key: key, body: data) unless validate_only
401
+ end
402
+ raise "No target files found at #{target_path}" unless found
403
+
404
+ target_folder = File.join(temp_dir, @name)
405
+ # Build a System for just this target
406
+ system = System.new([@name], temp_dir)
407
+ if variables["xtce_output"]
408
+ puts "Converting target #{@name} to .xtce files in #{variables["xtce_output"]}/#{@name}"
409
+ system.packet_config.to_xtce(variables["xtce_output"])
410
+ end
411
+ unless validate_only
412
+ build_target_archive(rubys3_client, temp_dir, target_folder)
413
+ system = update_store(system)
414
+ deploy_microservices(gem_path, variables, system)
415
+ ConfigTopic.write({ kind: 'created', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
416
+ end
417
+ ensure
418
+ FileUtils.remove_entry(temp_dir) if temp_dir and File.exist?(temp_dir)
419
+ end
420
+ end
421
+
422
+ def undeploy
423
+ # Note: The plugin_model undeploy method removes all the microservices first
424
+ # so we don't need to destroy them here
425
+
426
+ rubys3_client = Aws::S3::Client.new
427
+ prefix = "#{@scope}/targets/#{@name}/"
428
+ rubys3_client.list_objects(bucket: 'config', prefix: prefix).contents.each do |object|
429
+ rubys3_client.delete_object(bucket: 'config', key: object.key)
430
+ end
431
+
432
+ self.class.get_model(name: @name, scope: @scope).limits_groups.each do |group|
433
+ Store.hdel("#{@scope}__limits_groups", group)
434
+ end
435
+ self.class.packets(@name, type: :CMD, scope: @scope).each do |packet|
436
+ Topic.del("#{@scope}__COMMAND__{#{@name}}__#{packet['packet_name']}")
437
+ Topic.del("#{@scope}__DECOMCMD__{#{@name}}__#{packet['packet_name']}")
438
+ end
439
+ self.class.packets(@name, scope: @scope).each do |packet|
440
+ Topic.del("#{@scope}__TELEMETRY__{#{@name}}__#{packet['packet_name']}")
441
+ Topic.del("#{@scope}__DECOM__{#{@name}}__#{packet['packet_name']}")
442
+ CvtModel.del(target_name: @name, packet_name: packet['packet_name'], scope: @scope)
443
+ LimitsEventTopic.delete(@name, packet['packet_name'], scope: @scope)
444
+ end
445
+ Store.del("#{@scope}__openc3tlm__#{@name}")
446
+ Store.del("#{@scope}__openc3cmd__#{@name}")
447
+
448
+ # Note: these match the names of the services in deploy_microservices
449
+ %w(DECOM COMMANDLOG DECOMCMDLOG PACKETLOG DECOMLOG REDUCER CLEANUP).each do |type|
450
+ model = MicroserviceModel.get_model(name: "#{@scope}__#{type}__#{@name}", scope: @scope)
451
+ model.destroy if model
452
+ end
453
+
454
+ ConfigTopic.write({ kind: 'deleted', type: 'target', name: @name, plugin: @plugin }, scope: @scope)
455
+ end
456
+
457
+ ##################################################
458
+ # The following methods are implementation details
459
+ ##################################################
460
+
461
+ # Called by the ERB template to render a partial
462
+ def render(template_name, options = {})
463
+ raise "Partial name '#{template_name}' must begin with an underscore." if File.basename(template_name)[0] != '_'
464
+
465
+ b = binding
466
+ b.local_variable_set(:target_name, @name)
467
+ if options[:locals]
468
+ options[:locals].each { |key, value| b.local_variable_set(key, value) }
469
+ end
470
+
471
+ # Assume the file is there. If not we raise a pretty obvious error
472
+ if File.expand_path(template_name) == template_name # absolute path
473
+ path = template_name
474
+ else # relative to the current @filename
475
+ path = File.join(File.dirname(@filename), template_name)
476
+ end
477
+
478
+ begin
479
+ OpenC3.set_working_dir(File.dirname(path)) do
480
+ return ERB.new(File.read(path), trim_mode: "-").result(b)
481
+ end
482
+ rescue => error
483
+ raise "ERB error parsing: #{path}: #{error.formatted}"
484
+ end
485
+ end
486
+
487
+ def build_target_archive(rubys3_client, temp_dir, target_folder)
488
+ target_files = []
489
+ Find.find(target_folder) { |file| target_files << file }
490
+ target_files.sort!
491
+ hash = OpenC3.hash_files(target_files, nil, 'SHA256').hexdigest
492
+ File.open(File.join(target_folder, 'target_id.txt'), 'wb') { |file| file.write(hash) }
493
+ key = "#{@scope}/targets/#{@name}/target_id.txt"
494
+ rubys3_client.put_object(bucket: 'config', key: key, body: hash)
495
+
496
+ # Create target archive zip file
497
+ prefix = File.dirname(target_folder) + '/'
498
+ output_file = File.join(temp_dir, @name + '_' + hash + '.zip')
499
+ Zip.continue_on_exists_proc = true
500
+ Zip::File.open(output_file, Zip::File::CREATE) do |zipfile|
501
+ target_files.each do |target_file|
502
+ zip_file_path = target_file.delete_prefix(prefix)
503
+ if File.directory?(target_file)
504
+ zipfile.mkdir(zip_file_path)
505
+ else
506
+ zipfile.add(zip_file_path, target_file)
507
+ end
508
+ end
509
+ end
510
+
511
+ # Write Target Archive to S3 Bucket
512
+ File.open(output_file, 'rb') do |file|
513
+ s3_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_current.zip"
514
+ rubys3_client.put_object(bucket: 'config', key: s3_key, body: file)
515
+ end
516
+ File.open(output_file, 'rb') do |file|
517
+ s3_key = key = "#{@scope}/target_archives/#{@name}/#{@name}_#{hash}.zip"
518
+ rubys3_client.put_object(bucket: 'config', key: s3_key, body: file)
519
+ end
520
+ end
521
+
522
+ def update_store(system)
523
+ target = system.targets[@name]
524
+
525
+ # Add in the information from the target and update
526
+ @requires = target.requires
527
+ @ignored_parameters = target.ignored_parameters
528
+ @ignored_items = target.ignored_items
529
+ @cmd_tlm_files = target.cmd_tlm_files
530
+ @cmd_unique_id_mode = target.cmd_unique_id_mode
531
+ @tlm_unique_id_mode = target.tlm_unique_id_mode
532
+ @id = target.id
533
+ @limits_groups = system.limits.groups.keys
534
+ update()
535
+
536
+ # Store Packet Definitions
537
+ system.telemetry.all.each do |target_name, packets|
538
+ Store.del("#{@scope}__openc3tlm__#{target_name}")
539
+ packets.each do |packet_name, packet|
540
+ Logger.info "Configuring tlm packet: #{target_name} #{packet_name}"
541
+ begin
542
+ Store.hset("#{@scope}__openc3tlm__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
543
+ rescue JSON::GeneratorError => err
544
+ Logger.error("Invalid text present in #{target_name} #{packet_name} tlm packet")
545
+ raise err
546
+ end
547
+ json_hash = Hash.new
548
+ packet.sorted_items.each do |item|
549
+ json_hash[item.name] = nil
550
+ end
551
+ CvtModel.set(json_hash, target_name: packet.target_name, packet_name: packet.packet_name, scope: @scope)
552
+ end
553
+ end
554
+ system.commands.all.each do |target_name, packets|
555
+ Store.del("#{@scope}__openc3cmd__#{target_name}")
556
+ packets.each do |packet_name, packet|
557
+ Logger.info "Configuring cmd packet: #{target_name} #{packet_name}"
558
+ begin
559
+ Store.hset("#{@scope}__openc3cmd__#{target_name}", packet_name, JSON.generate(packet.as_json(:allow_nan => true)))
560
+ rescue JSON::GeneratorError => err
561
+ Logger.error("Invalid text present in #{target_name} #{packet_name} cmd packet")
562
+ raise err
563
+ end
564
+ end
565
+ end
566
+ # Store Limits Groups
567
+ system.limits.groups.each do |group, items|
568
+ begin
569
+ Store.hset("#{@scope}__limits_groups", group, JSON.generate(items))
570
+ rescue JSON::GeneratorError => err
571
+ Logger.error("Invalid text present in #{group} limits group")
572
+ raise err
573
+ end
574
+ end
575
+ # Merge in Limits Sets
576
+ sets = Store.hgetall("#{@scope}__limits_sets")
577
+ sets ||= {}
578
+ system.limits.sets.each do |set|
579
+ sets[set.to_s] = "false" unless sets.key?(set.to_s)
580
+ end
581
+ Store.hmset("#{@scope}__limits_sets", *sets)
582
+
583
+ return system
584
+ end
585
+
586
+ def deploy_microservices(gem_path, variables, system)
587
+ command_topic_list = []
588
+ decom_command_topic_list = []
589
+ packet_topic_list = []
590
+ decom_topic_list = []
591
+ begin
592
+ system.commands.packets(@name).each do |packet_name, packet|
593
+ command_topic_list << "#{@scope}__COMMAND__{#{@name}}__#{packet_name}"
594
+ decom_command_topic_list << "#{@scope}__DECOMCMD__{#{@name}}__#{packet_name}"
595
+ end
596
+ rescue
597
+ # No command packets for this target
598
+ end
599
+ begin
600
+ system.telemetry.packets(@name).each do |packet_name, packet|
601
+ packet_topic_list << "#{@scope}__TELEMETRY__{#{@name}}__#{packet_name}"
602
+ decom_topic_list << "#{@scope}__DECOM__{#{@name}}__#{packet_name}"
603
+ end
604
+ rescue
605
+ # No telemetry packets for this target
606
+ end
607
+ # It's ok to call initialize_streams with an empty array
608
+ Topic.initialize_streams(command_topic_list)
609
+ Topic.initialize_streams(decom_command_topic_list)
610
+ Topic.initialize_streams(packet_topic_list)
611
+ Topic.initialize_streams(decom_topic_list)
612
+
613
+ unless command_topic_list.empty?
614
+ # CommandLog Microservice
615
+ microservice_name = "#{@scope}__COMMANDLOG__#{@name}"
616
+ microservice = MicroserviceModel.new(
617
+ name: microservice_name,
618
+ folder_name: @folder_name,
619
+ cmd: ["ruby", "log_microservice.rb", microservice_name],
620
+ work_dir: '/openc3/lib/openc3/microservices',
621
+ options: [
622
+ ["RAW_OR_DECOM", "RAW"],
623
+ ["CMD_OR_TLM", "CMD"],
624
+ ["CYCLE_TIME", @cmd_log_cycle_time],
625
+ ["CYCLE_SIZE", @cmd_log_cycle_size]
626
+ ],
627
+ topics: command_topic_list,
628
+ target_names: [@name],
629
+ plugin: @plugin,
630
+ needs_dependencies: @needs_dependencies,
631
+ scope: @scope
632
+ )
633
+ microservice.create
634
+ microservice.deploy(gem_path, variables)
635
+ Logger.info "Configured microservice #{microservice_name}"
636
+
637
+ # DecomCmdLog Microservice
638
+ microservice_name = "#{@scope}__DECOMCMDLOG__#{@name}"
639
+ microservice = MicroserviceModel.new(
640
+ name: microservice_name,
641
+ folder_name: @folder_name,
642
+ cmd: ["ruby", "log_microservice.rb", microservice_name],
643
+ work_dir: '/openc3/lib/openc3/microservices',
644
+ options: [
645
+ ["RAW_OR_DECOM", "DECOM"],
646
+ ["CMD_OR_TLM", "CMD"],
647
+ ["CYCLE_TIME", @cmd_decom_log_cycle_time],
648
+ ["CYCLE_SIZE", @cmd_decom_log_cycle_size]
649
+ ],
650
+ topics: decom_command_topic_list,
651
+ target_names: [@name],
652
+ plugin: @plugin,
653
+ needs_dependencies: @needs_dependencies,
654
+ scope: @scope
655
+ )
656
+ microservice.create
657
+ microservice.deploy(gem_path, variables)
658
+ Logger.info "Configured microservice #{microservice_name}"
659
+ end
660
+
661
+ unless packet_topic_list.empty?
662
+ # PacketLog Microservice
663
+ microservice_name = "#{@scope}__PACKETLOG__#{@name}"
664
+ microservice = MicroserviceModel.new(
665
+ name: microservice_name,
666
+ folder_name: @folder_name,
667
+ cmd: ["ruby", "log_microservice.rb", microservice_name],
668
+ work_dir: '/openc3/lib/openc3/microservices',
669
+ options: [
670
+ ["RAW_OR_DECOM", "RAW"],
671
+ ["CMD_OR_TLM", "TLM"],
672
+ ["CYCLE_TIME", @tlm_log_cycle_time],
673
+ ["CYCLE_SIZE", @tlm_log_cycle_size]
674
+ ],
675
+ topics: packet_topic_list,
676
+ target_names: [@name],
677
+ plugin: @plugin,
678
+ needs_dependencies: @needs_dependencies,
679
+ scope: @scope
680
+ )
681
+ microservice.create
682
+ microservice.deploy(gem_path, variables)
683
+ Logger.info "Configured microservice #{microservice_name}"
684
+
685
+ # DecomLog Microservice
686
+ microservice_name = "#{@scope}__DECOMLOG__#{@name}"
687
+ microservice = MicroserviceModel.new(
688
+ name: microservice_name,
689
+ folder_name: @folder_name,
690
+ cmd: ["ruby", "log_microservice.rb", microservice_name],
691
+ work_dir: '/openc3/lib/openc3/microservices',
692
+ options: [
693
+ ["RAW_OR_DECOM", "DECOM"],
694
+ ["CMD_OR_TLM", "TLM"],
695
+ ["CYCLE_TIME", @tlm_decom_log_cycle_time],
696
+ ["CYCLE_SIZE", @tlm_decom_log_cycle_size]
697
+ ],
698
+ topics: decom_topic_list,
699
+ target_names: [@name],
700
+ plugin: @plugin,
701
+ needs_dependencies: @needs_dependencies,
702
+ scope: @scope
703
+ )
704
+ microservice.create
705
+ microservice.deploy(gem_path, variables)
706
+ Logger.info "Configured microservice #{microservice_name}"
707
+
708
+ # Decommutation Microservice
709
+ microservice_name = "#{@scope}__DECOM__#{@name}"
710
+ microservice = MicroserviceModel.new(
711
+ name: microservice_name,
712
+ folder_name: @folder_name,
713
+ cmd: ["ruby", "decom_microservice.rb", microservice_name],
714
+ work_dir: '/openc3/lib/openc3/microservices',
715
+ topics: packet_topic_list,
716
+ target_names: [@name],
717
+ plugin: @plugin,
718
+ needs_dependencies: @needs_dependencies,
719
+ scope: @scope
720
+ )
721
+ microservice.create
722
+ microservice.deploy(gem_path, variables)
723
+ Logger.info "Configured microservice #{microservice_name}"
724
+
725
+ # Reducer Microservice
726
+ microservice_name = "#{@scope}__REDUCER__#{@name}"
727
+ microservice = MicroserviceModel.new(
728
+ name: microservice_name,
729
+ folder_name: @folder_name,
730
+ cmd: ["ruby", "reducer_microservice.rb", microservice_name],
731
+ work_dir: '/openc3/lib/openc3/microservices',
732
+ topics: decom_topic_list,
733
+ plugin: @plugin,
734
+ needs_dependencies: @needs_dependencies,
735
+ scope: @scope
736
+ )
737
+ microservice.create
738
+ microservice.deploy(gem_path, variables)
739
+ Logger.info "Configured microservice #{microservice_name}"
740
+ end
741
+
742
+ if @cmd_log_retain_time or @cmd_decom_log_retain_time or @tlm_log_retain_time or @tlm_decom_log_retain_time or
743
+ @reduced_minute_log_retain_time or @reduced_hour_log_retain_time or @reduced_day_log_retain_time
744
+ # Cleanup Microservice
745
+ microservice_name = "#{@scope}__CLEANUP__#{@name}"
746
+ microservice = MicroserviceModel.new(
747
+ name: microservice_name,
748
+ cmd: ["ruby", "cleanup_microservice.rb", microservice_name],
749
+ work_dir: '/openc3/lib/openc3/microservices',
750
+ plugin: @plugin,
751
+ scope: @scope
752
+ )
753
+ microservice.create
754
+ microservice.deploy(gem_path, variables)
755
+ Logger.info "Configured microservice #{microservice_name}"
756
+ end
757
+ end
758
+ end
759
+ end