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,59 @@
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/models/model'
21
+
22
+ module OpenC3
23
+ class MetricModel < EphemeralModel
24
+ PRIMARY_KEY = '__openc3__metric'.freeze
25
+
26
+ # NOTE: The following three class methods are used by the ModelController
27
+ # and are reimplemented to enable various Model class methods to work
28
+ def self.get(name:, scope:)
29
+ super("#{scope}#{PRIMARY_KEY}", name: name)
30
+ end
31
+
32
+ def self.names(scope:)
33
+ super("#{scope}#{PRIMARY_KEY}")
34
+ end
35
+
36
+ def self.all(scope:)
37
+ super("#{scope}#{PRIMARY_KEY}")
38
+ end
39
+
40
+ def self.destroy(scope:, name:)
41
+ EphemeralStore.hdel("#{scope}#{PRIMARY_KEY}", name)
42
+ end
43
+
44
+ def initialize(name:, scope:, metric_name:, label_list:)
45
+ super("#{scope}#{PRIMARY_KEY}", name: name, scope: scope)
46
+ @metric_name = metric_name
47
+ @label_list = label_list
48
+ end
49
+
50
+ def as_json(*a)
51
+ {
52
+ 'name' => @name,
53
+ 'updated_at' => @updated_at,
54
+ 'metric_name' => @metric_name,
55
+ 'label_list' => @label_list
56
+ }
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,206 @@
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/utilities/s3'
23
+
24
+ module OpenC3
25
+ class MicroserviceModel < Model
26
+ PRIMARY_KEY = 'openc3_microservices'
27
+
28
+ attr_accessor :cmd
29
+ attr_accessor :options
30
+ attr_accessor :needs_dependencies
31
+
32
+ # NOTE: The following three class methods are used by the ModelController
33
+ # and are reimplemented to enable various Model class methods to work
34
+ def self.get(name:, scope: nil)
35
+ super(PRIMARY_KEY, name: name)
36
+ end
37
+
38
+ def self.names(scope: nil)
39
+ scoped = []
40
+ unscoped = super(PRIMARY_KEY)
41
+ unscoped.each do |name|
42
+ if !scope or name.split("__")[0] == scope
43
+ scoped << name
44
+ end
45
+ end
46
+ scoped
47
+ end
48
+
49
+ def self.all(scope: nil)
50
+ scoped = {}
51
+ unscoped = super(PRIMARY_KEY)
52
+ unscoped.each do |name, json|
53
+ if !scope or name.split("__")[0] == scope
54
+ scoped[name] = json
55
+ end
56
+ end
57
+ scoped
58
+ end
59
+
60
+ # Called by the PluginModel to allow this class to validate it's top-level keyword: "MICROSERVICE"
61
+ def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
62
+ case keyword
63
+ when 'MICROSERVICE'
64
+ parser.verify_num_parameters(2, 2, "#{keyword} <Folder Name> <Name>")
65
+ # Create name by adding scope and type 'USER' to indicate where this microservice came from
66
+ return self.new(folder_name: parameters[0], name: "#{scope}__USER__#{parameters[1].upcase}", plugin: plugin, needs_dependencies: needs_dependencies, scope: scope)
67
+ else
68
+ raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Microservice: #{keyword} #{parameters.join(" ")}")
69
+ end
70
+ end
71
+
72
+ # Create a microservice model to be deployed to S3
73
+ def initialize(
74
+ name:,
75
+ folder_name: nil,
76
+ cmd: [],
77
+ work_dir: '.',
78
+ env: {},
79
+ topics: [],
80
+ target_names: [],
81
+ options: [],
82
+ container: nil,
83
+ updated_at: nil,
84
+ plugin: nil,
85
+ needs_dependencies: false,
86
+ scope:
87
+ )
88
+ parts = name.split("__")
89
+ if parts.length != 3
90
+ raise "name '#{name}' must be formatted as SCOPE__TYPE__NAME"
91
+ end
92
+ if parts[0] != scope
93
+ raise "name '#{name}' scope '#{parts[0]}' doesn't match scope parameter '#{scope}'"
94
+ end
95
+
96
+ super(PRIMARY_KEY, name: name, updated_at: updated_at, plugin: plugin, scope: scope)
97
+ @folder_name = folder_name
98
+ @cmd = cmd
99
+ @work_dir = work_dir
100
+ @env = env
101
+ @topics = topics
102
+ @target_names = target_names
103
+ @options = options
104
+ @container = container
105
+ @needs_dependencies = needs_dependencies
106
+ end
107
+
108
+ def as_json(*a)
109
+ {
110
+ 'name' => @name,
111
+ 'folder_name' => @folder_name,
112
+ 'cmd' => @cmd,
113
+ 'work_dir' => @work_dir,
114
+ 'env' => @env,
115
+ 'topics' => @topics,
116
+ 'target_names' => @target_names,
117
+ 'options' => @options,
118
+ 'container' => @container,
119
+ 'updated_at' => @updated_at,
120
+ 'plugin' => @plugin,
121
+ 'needs_dependencies' => @needs_dependencies,
122
+ }
123
+ end
124
+
125
+ def as_config
126
+ result = "MICROSERVICE #{@folder_name ? @folder_name : 'nil'} #{@name.split("__")[-1]}\n"
127
+ result << " CMD #{@cmd.join(' ')}\n"
128
+ result << " WORK_DIR \"#{@work_dir}\"\n"
129
+ @topics.each do |topic_name|
130
+ result << " TOPIC #{topic_name}\n"
131
+ end
132
+ @target_names.each do |target_name|
133
+ result << " TARGET_NAME #{target_name}\n"
134
+ end
135
+ @env.each do |key, value|
136
+ result << " ENV #{key} \"#{value}\"\n"
137
+ end
138
+ @options.each do |option|
139
+ result << " OPTION #{option.join(" ")}\n"
140
+ end
141
+ result << " CONTAINER #{@container}\n" if @container != 'openc3-base'
142
+ result
143
+ end
144
+
145
+ def handle_config(parser, keyword, parameters)
146
+ case keyword
147
+ when 'ENV'
148
+ parser.verify_num_parameters(2, 2, "#{keyword} <Key> <Value>")
149
+ @env[parameters[0]] = parameters[1]
150
+ when 'WORK_DIR'
151
+ parser.verify_num_parameters(1, 1, "#{keyword} <Dir>")
152
+ @work_dir = parameters[0]
153
+ when 'TOPIC'
154
+ parser.verify_num_parameters(1, 1, "#{keyword} <Topic Name>")
155
+ @topics << parameters[0]
156
+ when 'TARGET_NAME'
157
+ parser.verify_num_parameters(1, 1, "#{keyword} <Target Name>")
158
+ @target_names << parameters[0]
159
+ when 'CMD'
160
+ parser.verify_num_parameters(1, nil, "#{keyword} <Args>")
161
+ @cmd = parameters.dup
162
+ when 'OPTION'
163
+ parser.verify_num_parameters(2, nil, "#{keyword} <Option Name> <Option Values>")
164
+ @options << parameters.dup
165
+ when 'CONTAINER'
166
+ parser.verify_num_parameters(1, 1, "#{keyword} <Container Image Name>")
167
+ @container = parameters[0]
168
+ else
169
+ raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Microservice: #{keyword} #{parameters.join(" ")}")
170
+ end
171
+ return nil
172
+ end
173
+
174
+ def deploy(gem_path, variables, validate_only: false)
175
+ return unless @folder_name
176
+
177
+ variables["microservice_name"] = @name
178
+ start_path = "/microservices/#{@folder_name}/"
179
+ Dir.glob(gem_path + start_path + "**/*") do |filename|
180
+ next if filename == '.' or filename == '..' or File.directory?(filename)
181
+
182
+ path = filename.split(gem_path)[-1]
183
+ key = "#{@scope}/microservices/#{@name}/" + path.split(start_path)[-1]
184
+
185
+ # Load microservice files
186
+ data = File.read(filename, mode: "rb")
187
+ OpenC3.set_working_dir(File.dirname(filename)) do
188
+ data = ERB.new(data, trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable?
189
+ end
190
+ unless validate_only
191
+ Aws::S3::Client.new.put_object(bucket: 'config', key: key, body: data)
192
+ ConfigTopic.write({ kind: 'created', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
193
+ end
194
+ end
195
+ end
196
+
197
+ def undeploy
198
+ rubys3_client = Aws::S3::Client.new
199
+ prefix = "#{@scope}/microservices/#{@name}/"
200
+ rubys3_client.list_objects(bucket: 'config', prefix: prefix).contents.each do |object|
201
+ rubys3_client.delete_object(bucket: 'config', key: object.key)
202
+ end
203
+ ConfigTopic.write({ kind: 'deleted', type: 'microservice', name: @name, plugin: @plugin }, scope: @scope)
204
+ end
205
+ end
206
+ end
@@ -0,0 +1,74 @@
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/models/model'
21
+
22
+ module OpenC3
23
+ class MicroserviceStatusModel < EphemeralModel
24
+ PRIMARY_KEY = 'openc3_microservice_status'
25
+
26
+ attr_accessor :state
27
+ attr_accessor :count
28
+ attr_accessor :error
29
+ attr_accessor :custom
30
+
31
+ # NOTE: The following three class methods are used by the ModelController
32
+ # and are reimplemented to enable various Model class methods to work
33
+ def self.get(name:, scope:)
34
+ super("#{scope}__#{PRIMARY_KEY}", name: name)
35
+ end
36
+
37
+ def self.names(scope:)
38
+ super("#{scope}__#{PRIMARY_KEY}")
39
+ end
40
+
41
+ def self.all(scope:)
42
+ super("#{scope}__#{PRIMARY_KEY}")
43
+ end
44
+
45
+ def initialize(
46
+ name:,
47
+ state: nil,
48
+ count: 0,
49
+ error: nil,
50
+ custom: nil,
51
+ updated_at: nil,
52
+ plugin: nil,
53
+ scope:
54
+ )
55
+ super("#{scope}__#{PRIMARY_KEY}", name: name, updated_at: updated_at, plugin: plugin, scope: scope)
56
+ @state = state
57
+ @count = count
58
+ @error = error
59
+ @custom = custom
60
+ end
61
+
62
+ def as_json(*a)
63
+ {
64
+ 'name' => @name,
65
+ 'state' => @state,
66
+ 'count' => @count,
67
+ 'error' => @error.as_json(:allow_nan => true),
68
+ 'custom' => @custom.as_json(:allow_nan => true),
69
+ 'plugin' => @plugin,
70
+ 'updated_at' => @updated_at
71
+ }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,204 @@
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/utilities/store'
21
+ require 'openc3/config/config_parser'
22
+
23
+ module OpenC3
24
+ class Model
25
+ attr_accessor :name
26
+ attr_accessor :updated_at
27
+ attr_accessor :plugin
28
+ attr_accessor :scope
29
+
30
+ def self.store
31
+ Store
32
+ end
33
+
34
+ # NOTE: The following three methods must be reimplemented by Model subclasses
35
+ # without primary_key to support other class methods.
36
+
37
+ # @return [Hash|nil] Hash of this model or nil if name not found under primary_key
38
+ def self.get(primary_key, name:)
39
+ json = store.hget(primary_key, name)
40
+ if json
41
+ return JSON.parse(json, :allow_nan => true, :create_additions => true)
42
+ else
43
+ return nil
44
+ end
45
+ end
46
+
47
+ # @return [Array<String>] All the names stored under the primary key
48
+ def self.names(primary_key)
49
+ store.hkeys(primary_key).sort
50
+ end
51
+
52
+ # @return [Array<Hash>] All the models (as Hash objects) stored under the primary key
53
+ def self.all(primary_key)
54
+ hash = store.hgetall(primary_key)
55
+ hash.each do |key, value|
56
+ hash[key] = JSON.parse(value, :allow_nan => true, :create_additions => true)
57
+ end
58
+ hash
59
+ end
60
+ # END NOTE
61
+
62
+ # Loops over all items and returns objects that match a key value pair
63
+ def self.filter(key, value, scope:, use_regex: false)
64
+ filtered = {}
65
+ results = all(scope: scope)
66
+ regex = nil
67
+ regex = Regexp.new(value) if use_regex
68
+ results.each do |name, result|
69
+ if regex
70
+ if result[key] =~ regex
71
+ filtered[name] = result
72
+ end
73
+ else
74
+ if result[key] == value
75
+ filtered[name] = result
76
+ end
77
+ end
78
+ end
79
+ return filtered
80
+ end
81
+
82
+ # Sets (updates) the redis hash of this model
83
+ def self.set(json, scope:)
84
+ json[:scope] = scope
85
+ json.transform_keys!(&:to_sym)
86
+ self.new(**json).create(force: true)
87
+ end
88
+
89
+ # @return [Model] Model generated from the passed JSON
90
+ def self.from_json(json, scope:)
91
+ json = JSON.parse(json, :allow_nan => true, :create_additions => true) if String === json
92
+ raise "json data is nil" if json.nil?
93
+
94
+ json[:scope] = scope
95
+ json.transform_keys!(&:to_sym)
96
+ self.new(**json, scope: scope)
97
+ end
98
+
99
+ # Calls self.get and then from_json to turn the Hash configuration into a Ruby Model object.
100
+ # @return [Object|nil] Model object or nil if name not found under primary_key
101
+ def self.get_model(name:, scope:)
102
+ json = get(name: name, scope: scope)
103
+ if json
104
+ return from_json(json, scope: scope)
105
+ else
106
+ return nil
107
+ end
108
+ end
109
+
110
+ # @return [Array<Object>] All the models (as Model objects) stored under the primary key
111
+ def self.get_all_models(scope:)
112
+ models = {}
113
+ all(scope: scope).each { |name, json| models[name] = from_json(json, scope: scope) }
114
+ models
115
+ end
116
+
117
+ # @return [Array<Object>] All the models (as Model objects) stored under the primary key
118
+ # which have the plugin attribute
119
+ def self.find_all_by_plugin(plugin:, scope:)
120
+ result = {}
121
+ models = get_all_models(scope: scope)
122
+ models.each do |name, model|
123
+ result[name] = model if model.plugin == plugin
124
+ end
125
+ result
126
+ end
127
+
128
+ def self.handle_config(parser, model, keyword, parameters)
129
+ raise "must be implemented by subclass"
130
+ end
131
+
132
+ # Store the primary key and keyword arguments
133
+ def initialize(primary_key, **kw_args)
134
+ @primary_key = primary_key
135
+ @name = kw_args[:name]
136
+ @updated_at = kw_args[:updated_at]
137
+ @plugin = kw_args[:plugin]
138
+ @scope = kw_args[:scope]
139
+ @destroyed = false
140
+ end
141
+
142
+ # Update the Redis hash at primary_key and set the field "name"
143
+ # to the JSON generated via calling as_json
144
+ def create(update: false, force: false)
145
+ unless force
146
+ existing = self.class.store.hget(@primary_key, @name)
147
+ if existing
148
+ raise "#{@primary_key}:#{@name} already exists at create" unless update
149
+ else
150
+ raise "#{@primary_key}:#{@name} doesn't exist at update" if update
151
+ end
152
+ end
153
+ @updated_at = Time.now.to_nsec_from_epoch
154
+ self.class.store.hset(@primary_key, @name, JSON.generate(self.as_json(:allow_nan => true)))
155
+ end
156
+
157
+ # Alias for create(update: true)
158
+ def update
159
+ create(update: true)
160
+ end
161
+
162
+ # Deploy the model into the OpenC3 system. Subclasses must implement this
163
+ # and typically create MicroserviceModels to implement.
164
+ def deploy(gem_path, variables)
165
+ raise "must be implemented by subclass"
166
+ end
167
+
168
+ # Undo the actions of deploy and remove the model from OpenC3.
169
+ # Subclasses must implement this as by default it is a noop.
170
+ def undeploy
171
+ end
172
+
173
+ # Delete the model from the Store
174
+ def destroy
175
+ @destroyed = true
176
+ undeploy()
177
+ self.class.store.hdel(@primary_key, @name)
178
+ end
179
+
180
+ # Indicate if destroy has been called
181
+ def destroyed?
182
+ @destroyed
183
+ end
184
+
185
+ # @return [Hash] JSON encoding of this model
186
+ def as_json(*a)
187
+ { 'name' => @name,
188
+ 'updated_at' => @updated_at,
189
+ 'plugin' => @plugin,
190
+ 'scope' => @scope }
191
+ end
192
+
193
+ # TODO: Not currently used but may be used by a XTCE or other format to OpenC3 conversion
194
+ def as_config
195
+ ""
196
+ end
197
+ end
198
+
199
+ class EphemeralModel < Model
200
+ def self.store
201
+ EphemeralStore
202
+ end
203
+ end
204
+ end
@@ -0,0 +1,122 @@
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
+ # https://www.rubydoc.info/gems/redis/Redis/Commands/SortedSets
21
+
22
+ require 'openc3/models/sorted_model'
23
+
24
+ module OpenC3
25
+ class NoteModel < SortedModel
26
+ NOTE_TYPE = 'note'.freeze
27
+ PRIMARY_KEY = '__NOTE'.freeze
28
+
29
+ def self.pk(scope)
30
+ "#{scope}#{PRIMARY_KEY}"
31
+ end
32
+
33
+ attr_reader :stop, :color, :description, :type
34
+
35
+ # @param [String] scope - OpenC3 scope to track event to
36
+ # @param [Integer] start - start of the event in seconds from Epoch
37
+ # @param [Integer] stop - stop of the event in seconds from Epoch
38
+ # @param [String] color - The event color
39
+ # @param [String] description - What the event is about
40
+ def initialize(
41
+ scope:,
42
+ start:,
43
+ stop:,
44
+ color: nil,
45
+ description:,
46
+ type: NOTE_TYPE,
47
+ updated_at: 0
48
+ )
49
+ super(start: start, scope: scope, updated_at: updated_at)
50
+ @start = start
51
+ @stop = stop
52
+ @color = color
53
+ @description = description
54
+ @type = type # For the as_json, from_json round trip
55
+ end
56
+
57
+ # Validates the instance variables: @start, @stop, @color, @description
58
+ def validate(update: false)
59
+ validate_start(update: update)
60
+ validate_stop()
61
+ validate_color()
62
+ end
63
+
64
+ def validate_stop()
65
+ unless @stop.is_a?(Integer)
66
+ raise SortedInputError.new "stop must be integer: #{@stop}"
67
+ end
68
+ if @stop.to_i < @start
69
+ raise SortedInputError.new "stop: #{@stop} must be >= start: #{@start}"
70
+ end
71
+ @stop = @stop.to_i
72
+ end
73
+
74
+ def validate_color()
75
+ if @color.nil?
76
+ @color = '#%06x' % (rand * 0xffffff)
77
+ end
78
+ unless @color =~ /(#*)([0-9,a-f,A-f]{6})/
79
+ raise SortedInputError.new "invalid color, must be in hex format, e.g. #FF0000"
80
+ end
81
+ @color = "##{@color}" unless @color.start_with?('#')
82
+ end
83
+
84
+ # Update the Redis hash at primary_key based on the initial passed start
85
+ # The member is set to the JSON generated via calling as_json
86
+ def create(update: false)
87
+ validate(update: update)
88
+ @updated_at = Time.now.to_nsec_from_epoch
89
+ NoteModel.destroy(scope: @scope, start: update) if update
90
+ Store.zadd(@primary_key, @start, JSON.generate(as_json(:allow_nan => true)))
91
+ if update
92
+ notify(kind: 'updated')
93
+ else
94
+ notify(kind: 'created')
95
+ end
96
+ end
97
+
98
+ # Update the Redis hash at primary_key
99
+ def update(start:, stop:, color:, description:)
100
+ orig_start = @start
101
+ @start = start
102
+ @stop = stop
103
+ @color = color
104
+ @description = description
105
+ create(update: orig_start)
106
+ end
107
+
108
+ # @return [Hash] generated from the NoteModel
109
+ def as_json(*a)
110
+ return {
111
+ 'scope' => @scope,
112
+ 'start' => @start,
113
+ 'stop' => @stop,
114
+ 'color' => @color,
115
+ 'description' => @description,
116
+ 'type' => NOTE_TYPE,
117
+ 'updated_at' => @updated_at,
118
+ }
119
+ end
120
+ alias to_s as_json
121
+ end
122
+ end
@@ -0,0 +1,40 @@
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 OpenC3
21
+ class NotificationModel
22
+ attr_reader :time, :severity, :url, :title, :body
23
+
24
+ def initialize(time:, severity:, url:, title:, body:)
25
+ @time = time
26
+ @severity = severity
27
+ @url = url
28
+ @title = title
29
+ @body = body
30
+ end
31
+
32
+ def as_json(*a)
33
+ { "time" => @time,
34
+ "severity" => @severity,
35
+ "url" => @url,
36
+ "title" => @title,
37
+ "body" => @body }
38
+ end
39
+ end
40
+ end