openc3 7.3.0 → 7.4.1

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 (499) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Guardfile +0 -0
  4. data/LICENSE.md +0 -0
  5. data/README.md +0 -0
  6. data/Rakefile +0 -0
  7. data/bin/openc3cli +139 -0
  8. data/bin/pipuninstall +0 -0
  9. data/bin/uvinstall +10 -3
  10. data/data/config/_array_params.yaml +0 -0
  11. data/data/config/_canvas_values.yaml +0 -0
  12. data/data/config/_graph_params.yaml +0 -0
  13. data/data/config/_id_items.yaml +0 -0
  14. data/data/config/_id_params.yaml +0 -0
  15. data/data/config/_interfaces.yaml +0 -0
  16. data/data/config/_items.yaml +0 -0
  17. data/data/config/_params.yaml +0 -0
  18. data/data/config/command.yaml +0 -0
  19. data/data/config/command_modifiers.yaml +2 -0
  20. data/data/config/command_telemetry.yaml +0 -0
  21. data/data/config/conversions.yaml +0 -0
  22. data/data/config/graph_settings.yaml +0 -0
  23. data/data/config/interface_modifiers.yaml +103 -1
  24. data/data/config/item_modifiers.yaml +0 -0
  25. data/data/config/microservice.yaml +5 -2
  26. data/data/config/param_item_modifiers.yaml +0 -0
  27. data/data/config/parameter_modifiers.yaml +0 -0
  28. data/data/config/plugins.yaml +0 -0
  29. data/data/config/processors.yaml +0 -0
  30. data/data/config/protocols.yaml +0 -0
  31. data/data/config/screen.yaml +0 -0
  32. data/data/config/settings.yaml +0 -0
  33. data/data/config/table_manager.yaml +0 -0
  34. data/data/config/table_parameter_modifiers.yaml +0 -0
  35. data/data/config/target.yaml +0 -0
  36. data/data/config/target_config.yaml +0 -0
  37. data/data/config/telemetry.yaml +0 -0
  38. data/data/config/telemetry_modifiers.yaml +2 -0
  39. data/data/config/tool.yaml +0 -0
  40. data/data/config/unknown.yaml +0 -0
  41. data/data/config/widgets.yaml +6 -0
  42. data/data/xtce_schemas/SpaceSystem_20180204.xsd +0 -0
  43. data/data/xtce_schemas/xml.xsd +0 -0
  44. data/ext/openc3/ext/array/array.c +0 -0
  45. data/ext/openc3/ext/array/extconf.rb +0 -0
  46. data/ext/openc3/ext/buffered_file/buffered_file.c +0 -0
  47. data/ext/openc3/ext/buffered_file/extconf.rb +0 -0
  48. data/ext/openc3/ext/burst_protocol/burst_protocol.c +6 -0
  49. data/ext/openc3/ext/burst_protocol/extconf.rb +0 -0
  50. data/ext/openc3/ext/config_parser/config_parser.c +0 -0
  51. data/ext/openc3/ext/config_parser/extconf.rb +0 -0
  52. data/ext/openc3/ext/crc/crc.c +0 -0
  53. data/ext/openc3/ext/crc/extconf.rb +0 -0
  54. data/ext/openc3/ext/openc3_io/extconf.rb +0 -0
  55. data/ext/openc3/ext/openc3_io/openc3_io.c +0 -0
  56. data/ext/openc3/ext/packet/extconf.rb +0 -0
  57. data/ext/openc3/ext/packet/packet.c +0 -0
  58. data/ext/openc3/ext/platform/extconf.rb +0 -0
  59. data/ext/openc3/ext/platform/platform.c +4 -1
  60. data/ext/openc3/ext/polynomial_conversion/extconf.rb +0 -0
  61. data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +0 -0
  62. data/ext/openc3/ext/string/extconf.rb +0 -0
  63. data/ext/openc3/ext/string/string.c +0 -0
  64. data/ext/openc3/ext/structure/structure.c +49 -17
  65. data/ext/openc3/ext/tabbed_plots_config/extconf.rb +0 -0
  66. data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +0 -0
  67. data/ext/openc3/ext/telemetry/extconf.rb +0 -0
  68. data/ext/openc3/ext/telemetry/telemetry.c +0 -0
  69. data/lib/cosmos.rb +0 -0
  70. data/lib/cosmosc2.rb +0 -0
  71. data/lib/openc3/accessors/accessor.rb +0 -0
  72. data/lib/openc3/accessors/binary_accessor.rb +63 -9
  73. data/lib/openc3/accessors/cbor_accessor.rb +0 -0
  74. data/lib/openc3/accessors/form_accessor.rb +0 -0
  75. data/lib/openc3/accessors/html_accessor.rb +0 -0
  76. data/lib/openc3/accessors/http_accessor.rb +0 -0
  77. data/lib/openc3/accessors/json_accessor.rb +0 -0
  78. data/lib/openc3/accessors/template_accessor.rb +0 -0
  79. data/lib/openc3/accessors/xml_accessor.rb +0 -0
  80. data/lib/openc3/accessors.rb +0 -0
  81. data/lib/openc3/api/README.md +0 -0
  82. data/lib/openc3/api/api.rb +0 -0
  83. data/lib/openc3/api/authorized_api.rb +0 -0
  84. data/lib/openc3/api/calendar_api.rb +0 -0
  85. data/lib/openc3/api/cmd_api.rb +1 -1
  86. data/lib/openc3/api/config_api.rb +0 -0
  87. data/lib/openc3/api/interface_api.rb +0 -0
  88. data/lib/openc3/api/limits_api.rb +0 -0
  89. data/lib/openc3/api/metrics_api.rb +1 -1
  90. data/lib/openc3/api/offline_access_api.rb +1 -1
  91. data/lib/openc3/api/router_api.rb +0 -0
  92. data/lib/openc3/api/settings_api.rb +22 -18
  93. data/lib/openc3/api/stash_api.rb +1 -1
  94. data/lib/openc3/api/target_api.rb +0 -0
  95. data/lib/openc3/api/tlm_api.rb +19 -14
  96. data/lib/openc3/bridge/bridge.rb +0 -0
  97. data/lib/openc3/bridge/bridge_config.rb +0 -0
  98. data/lib/openc3/bridge/bridge_interface_thread.rb +0 -0
  99. data/lib/openc3/bridge/bridge_router_thread.rb +0 -0
  100. data/lib/openc3/ccsds/ccsds_packet.rb +0 -0
  101. data/lib/openc3/ccsds/ccsds_parser.rb +0 -0
  102. data/lib/openc3/config/config_parser.rb +78 -17
  103. data/lib/openc3/config/meta_config_parser.rb +0 -0
  104. data/lib/openc3/conversions/bit_reverse_conversion.rb +0 -0
  105. data/lib/openc3/conversions/conversion.rb +0 -0
  106. data/lib/openc3/conversions/generic_conversion.rb +0 -0
  107. data/lib/openc3/conversions/ip_read_conversion.rb +0 -0
  108. data/lib/openc3/conversions/ip_write_conversion.rb +0 -0
  109. data/lib/openc3/conversions/object_read_conversion.rb +0 -0
  110. data/lib/openc3/conversions/object_write_conversion.rb +0 -0
  111. data/lib/openc3/conversions/packet_time_formatted_conversion.rb +0 -0
  112. data/lib/openc3/conversions/packet_time_seconds_conversion.rb +0 -0
  113. data/lib/openc3/conversions/polynomial_conversion.rb +0 -0
  114. data/lib/openc3/conversions/processor_conversion.rb +0 -0
  115. data/lib/openc3/conversions/received_count_conversion.rb +0 -0
  116. data/lib/openc3/conversions/received_time_formatted_conversion.rb +0 -0
  117. data/lib/openc3/conversions/received_time_seconds_conversion.rb +0 -0
  118. data/lib/openc3/conversions/segmented_polynomial_conversion.rb +0 -0
  119. data/lib/openc3/conversions/unix_time_conversion.rb +0 -0
  120. data/lib/openc3/conversions/unix_time_formatted_conversion.rb +0 -0
  121. data/lib/openc3/conversions/unix_time_seconds_conversion.rb +0 -0
  122. data/lib/openc3/conversions.rb +0 -0
  123. data/lib/openc3/core_ext/array.rb +0 -0
  124. data/lib/openc3/core_ext/binding.rb +0 -0
  125. data/lib/openc3/core_ext/class.rb +0 -0
  126. data/lib/openc3/core_ext/exception.rb +0 -0
  127. data/lib/openc3/core_ext/faraday.rb +0 -0
  128. data/lib/openc3/core_ext/file.rb +0 -0
  129. data/lib/openc3/core_ext/io.rb +0 -0
  130. data/lib/openc3/core_ext/kernel.rb +0 -0
  131. data/lib/openc3/core_ext/math.rb +0 -0
  132. data/lib/openc3/core_ext/matrix.rb +0 -0
  133. data/lib/openc3/core_ext/objectspace.rb +0 -0
  134. data/lib/openc3/core_ext/openc3_io.rb +0 -0
  135. data/lib/openc3/core_ext/range.rb +0 -0
  136. data/lib/openc3/core_ext/socket.rb +0 -0
  137. data/lib/openc3/core_ext/string.rb +0 -0
  138. data/lib/openc3/core_ext/stringio.rb +0 -0
  139. data/lib/openc3/core_ext/tempfile.rb +0 -0
  140. data/lib/openc3/core_ext/time.rb +0 -0
  141. data/lib/openc3/core_ext.rb +0 -0
  142. data/lib/openc3/ext/.keep +0 -0
  143. data/lib/openc3/interfaces/file_interface.rb +0 -0
  144. data/lib/openc3/interfaces/http_client_interface.rb +0 -0
  145. data/lib/openc3/interfaces/http_server_interface.rb +0 -0
  146. data/lib/openc3/interfaces/interface.rb +5 -4
  147. data/lib/openc3/interfaces/mqtt_interface.rb +0 -0
  148. data/lib/openc3/interfaces/mqtt_stream_interface.rb +2 -0
  149. data/lib/openc3/interfaces/protocols/burst_protocol.rb +27 -0
  150. data/lib/openc3/interfaces/protocols/cmd_response_protocol.rb +0 -0
  151. data/lib/openc3/interfaces/protocols/cobs_protocol.rb +0 -0
  152. data/lib/openc3/interfaces/protocols/crc_protocol.rb +0 -0
  153. data/lib/openc3/interfaces/protocols/fixed_protocol.rb +0 -0
  154. data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +0 -0
  155. data/lib/openc3/interfaces/protocols/length_protocol.rb +7 -0
  156. data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +7 -0
  157. data/lib/openc3/interfaces/protocols/protocol.rb +12 -4
  158. data/lib/openc3/interfaces/protocols/slip_protocol.rb +0 -0
  159. data/lib/openc3/interfaces/protocols/template_protocol.rb +2 -2
  160. data/lib/openc3/interfaces/protocols/terminated_protocol.rb +0 -0
  161. data/lib/openc3/interfaces/serial_interface.rb +2 -0
  162. data/lib/openc3/interfaces/simulated_target_interface.rb +0 -0
  163. data/lib/openc3/interfaces/stream_interface.rb +0 -0
  164. data/lib/openc3/interfaces/tcpip_client_interface.rb +2 -0
  165. data/lib/openc3/interfaces/tcpip_server_interface.rb +0 -0
  166. data/lib/openc3/interfaces/udp_interface.rb +16 -5
  167. data/lib/openc3/interfaces.rb +0 -0
  168. data/lib/openc3/io/buffered_file.rb +0 -0
  169. data/lib/openc3/io/io_multiplexer.rb +0 -0
  170. data/lib/openc3/io/json_api.rb +3 -2
  171. data/lib/openc3/io/json_api_object.rb +24 -3
  172. data/lib/openc3/io/json_drb.rb +20 -4
  173. data/lib/openc3/io/json_drb_object.rb +3 -2
  174. data/lib/openc3/io/json_drb_rack.rb +0 -0
  175. data/lib/openc3/io/json_rpc.rb +0 -0
  176. data/lib/openc3/io/posix_serial_driver.rb +0 -0
  177. data/lib/openc3/io/serial_driver.rb +0 -0
  178. data/lib/openc3/io/stderr.rb +0 -0
  179. data/lib/openc3/io/stdout.rb +0 -0
  180. data/lib/openc3/io/udp_sockets.rb +38 -8
  181. data/lib/openc3/io/win32_serial_driver.rb +1 -0
  182. data/lib/openc3/logs/buffered_packet_log_reader.rb +0 -0
  183. data/lib/openc3/logs/buffered_packet_log_writer.rb +0 -0
  184. data/lib/openc3/logs/log_writer.rb +0 -0
  185. data/lib/openc3/logs/packet_log_constants.rb +0 -0
  186. data/lib/openc3/logs/packet_log_reader.rb +23 -2
  187. data/lib/openc3/logs/packet_log_writer.rb +5 -0
  188. data/lib/openc3/logs/stream_log.rb +1 -1
  189. data/lib/openc3/logs/stream_log_pair.rb +0 -0
  190. data/lib/openc3/logs/text_log_writer.rb +0 -0
  191. data/lib/openc3/logs.rb +0 -0
  192. data/lib/openc3/microservices/cleanup_microservice.rb +0 -0
  193. data/lib/openc3/microservices/decom_common.rb +0 -0
  194. data/lib/openc3/microservices/decom_microservice.rb +0 -0
  195. data/lib/openc3/microservices/interface_decom_common.rb +2 -1
  196. data/lib/openc3/microservices/interface_microservice.rb +72 -25
  197. data/lib/openc3/microservices/log_microservice.rb +0 -0
  198. data/lib/openc3/microservices/microservice.rb +3 -3
  199. data/lib/openc3/microservices/multi_microservice.rb +1 -1
  200. data/lib/openc3/microservices/periodic_microservice.rb +2 -2
  201. data/lib/openc3/microservices/plugin_microservice.rb +0 -0
  202. data/lib/openc3/microservices/queue_microservice.rb +0 -0
  203. data/lib/openc3/microservices/router_microservice.rb +0 -0
  204. data/lib/openc3/microservices/scope_cleanup_microservice.rb +0 -0
  205. data/lib/openc3/microservices/text_log_microservice.rb +0 -0
  206. data/lib/openc3/migrations/20220420190000_log_stuff.rb +0 -0
  207. data/lib/openc3/migrations/20221202214600_add_target_names.rb +0 -0
  208. data/lib/openc3/migrations/20221210174900_convert_to_multi.rb +0 -0
  209. data/lib/openc3/migrations/20230915000002_no_scope_log_messages.rb +0 -0
  210. data/lib/openc3/migrations/20231022000000_tlm_viewer_config.rb +0 -0
  211. data/lib/openc3/migrations/20241208080000_no_critical_cmd.rb +0 -0
  212. data/lib/openc3/migrations/20241208080001_no_trigger_group.rb +0 -0
  213. data/lib/openc3/migrations/20250108060000_news_feed.rb +0 -0
  214. data/lib/openc3/migrations/20250402000000_periodic_only_default.rb +0 -0
  215. data/lib/openc3/migrations/20260203000000_remove_store_id.rb +0 -0
  216. data/lib/openc3/migrations/20260204000000_remove_decom_reducer.rb +0 -0
  217. data/lib/openc3/migrations/20260701000000_updated_at_to_int.rb +0 -0
  218. data/lib/openc3/migrations/20260704000000_default_bridge.rb +38 -0
  219. data/lib/openc3/migrations/20260731000000_system_health_json.rb +11 -0
  220. data/lib/openc3/models/activity_model.rb +0 -0
  221. data/lib/openc3/models/auth_model.rb +35 -7
  222. data/lib/openc3/models/bridge_model.rb +133 -0
  223. data/lib/openc3/models/config_keyword_model.rb +63 -0
  224. data/lib/openc3/models/cvt_model.rb +0 -0
  225. data/lib/openc3/models/db_sharded_model.rb +0 -0
  226. data/lib/openc3/models/environment_model.rb +0 -0
  227. data/lib/openc3/models/gem_model.rb +12 -9
  228. data/lib/openc3/models/host_interface_microservice_model.rb +114 -0
  229. data/lib/openc3/models/info_model.rb +0 -0
  230. data/lib/openc3/models/interface_model.rb +178 -19
  231. data/lib/openc3/models/interface_status_model.rb +0 -0
  232. data/lib/openc3/models/metadata_model.rb +0 -0
  233. data/lib/openc3/models/metric_model.rb +0 -0
  234. data/lib/openc3/models/microservice_model.rb +9 -22
  235. data/lib/openc3/models/microservice_status_model.rb +0 -0
  236. data/lib/openc3/models/migration_model.rb +0 -0
  237. data/lib/openc3/models/model.rb +0 -0
  238. data/lib/openc3/models/news_model.rb +0 -0
  239. data/lib/openc3/models/note_model.rb +0 -0
  240. data/lib/openc3/models/offline_access_model.rb +0 -0
  241. data/lib/openc3/models/ping_model.rb +0 -0
  242. data/lib/openc3/models/plugin_model.rb +9 -2
  243. data/lib/openc3/models/plugin_store_model.rb +0 -0
  244. data/lib/openc3/models/process_status_model.rb +0 -0
  245. data/lib/openc3/models/python_package_model.rb +4 -4
  246. data/lib/openc3/models/queue_model.rb +0 -0
  247. data/lib/openc3/models/reaction_model.rb +6 -3
  248. data/lib/openc3/models/reingest_job_model.rb +0 -0
  249. data/lib/openc3/models/router_model.rb +0 -0
  250. data/lib/openc3/models/router_status_model.rb +0 -0
  251. data/lib/openc3/models/scope_model.rb +51 -26
  252. data/lib/openc3/models/script_engine_model.rb +0 -0
  253. data/lib/openc3/models/script_status_model.rb +0 -0
  254. data/lib/openc3/models/secret_model.rb +0 -0
  255. data/lib/openc3/models/setting_model.rb +548 -3
  256. data/lib/openc3/models/sorted_model.rb +0 -0
  257. data/lib/openc3/models/stash_model.rb +0 -0
  258. data/lib/openc3/models/target_model.rb +30 -25
  259. data/lib/openc3/models/timeline_model.rb +0 -0
  260. data/lib/openc3/models/tool_config_model.rb +0 -0
  261. data/lib/openc3/models/tool_model.rb +1 -0
  262. data/lib/openc3/models/trigger_group_model.rb +0 -0
  263. data/lib/openc3/models/trigger_model.rb +20 -0
  264. data/lib/openc3/models/widget_model.rb +0 -0
  265. data/lib/openc3/operators/microservice_operator.rb +64 -22
  266. data/lib/openc3/operators/operator.rb +4 -4
  267. data/lib/openc3/packets/binary_accessor.rb +0 -0
  268. data/lib/openc3/packets/command_validator.rb +0 -0
  269. data/lib/openc3/packets/commands.rb +0 -0
  270. data/lib/openc3/packets/json_packet.rb +0 -0
  271. data/lib/openc3/packets/limits.rb +0 -0
  272. data/lib/openc3/packets/limits_response.rb +0 -0
  273. data/lib/openc3/packets/packet.rb +4 -0
  274. data/lib/openc3/packets/packet_config.rb +36 -1
  275. data/lib/openc3/packets/packet_item.rb +0 -0
  276. data/lib/openc3/packets/packet_item_limits.rb +0 -0
  277. data/lib/openc3/packets/parsers/format_string_parser.rb +0 -0
  278. data/lib/openc3/packets/parsers/limits_parser.rb +0 -0
  279. data/lib/openc3/packets/parsers/limits_response_parser.rb +0 -0
  280. data/lib/openc3/packets/parsers/packet_item_parser.rb +0 -0
  281. data/lib/openc3/packets/parsers/packet_parser.rb +0 -0
  282. data/lib/openc3/packets/parsers/processor_parser.rb +0 -0
  283. data/lib/openc3/packets/parsers/state_parser.rb +0 -0
  284. data/lib/openc3/packets/parsers/xtce_converter.rb +0 -0
  285. data/lib/openc3/packets/parsers/xtce_parser.rb +8 -1
  286. data/lib/openc3/packets/structure.rb +7 -1
  287. data/lib/openc3/packets/structure_item.rb +0 -0
  288. data/lib/openc3/packets/telemetry.rb +0 -0
  289. data/lib/openc3/processors/processor.rb +2 -0
  290. data/lib/openc3/processors/statistics_processor.rb +0 -0
  291. data/lib/openc3/processors/watermark_processor.rb +0 -0
  292. data/lib/openc3/processors.rb +0 -0
  293. data/lib/openc3/script/api_shared.rb +0 -0
  294. data/lib/openc3/script/autonomic.rb +12 -12
  295. data/lib/openc3/script/calendar.rb +0 -0
  296. data/lib/openc3/script/commands.rb +0 -0
  297. data/lib/openc3/script/critical_cmd.rb +0 -0
  298. data/lib/openc3/script/exceptions.rb +0 -0
  299. data/lib/openc3/script/extract.rb +0 -0
  300. data/lib/openc3/script/limits.rb +0 -0
  301. data/lib/openc3/script/metadata.rb +0 -0
  302. data/lib/openc3/script/packages.rb +0 -0
  303. data/lib/openc3/script/plugins.rb +0 -0
  304. data/lib/openc3/script/queue.rb +0 -0
  305. data/lib/openc3/script/screen.rb +0 -0
  306. data/lib/openc3/script/script.rb +2 -2
  307. data/lib/openc3/script/script_runner.rb +0 -0
  308. data/lib/openc3/script/storage.rb +4 -4
  309. data/lib/openc3/script/suite.rb +0 -0
  310. data/lib/openc3/script/suite_results.rb +0 -0
  311. data/lib/openc3/script/suite_runner.rb +26 -0
  312. data/lib/openc3/script/tables.rb +5 -1
  313. data/lib/openc3/script/telemetry.rb +9 -3
  314. data/lib/openc3/script/web_socket_api.rb +218 -145
  315. data/lib/openc3/script.rb +0 -0
  316. data/lib/openc3/script_engines/script_engine.rb +0 -0
  317. data/lib/openc3/streams/mqtt_stream.rb +0 -0
  318. data/lib/openc3/streams/serial_stream.rb +0 -0
  319. data/lib/openc3/streams/stream.rb +0 -0
  320. data/lib/openc3/streams/tcpip_client_stream.rb +0 -0
  321. data/lib/openc3/streams/tcpip_socket_stream.rb +0 -0
  322. data/lib/openc3/streams/web_socket_client_stream.rb +0 -0
  323. data/lib/openc3/subpacketizers/subpacketizer.rb +0 -0
  324. data/lib/openc3/system/system.rb +0 -0
  325. data/lib/openc3/system/target.rb +0 -0
  326. data/lib/openc3/system.rb +0 -0
  327. data/lib/openc3/tools/cmd_tlm_server/api.rb +0 -0
  328. data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +7 -0
  329. data/lib/openc3/tools/table_manager/table.rb +0 -0
  330. data/lib/openc3/tools/table_manager/table_config.rb +0 -0
  331. data/lib/openc3/tools/table_manager/table_item.rb +0 -0
  332. data/lib/openc3/tools/table_manager/table_item_parser.rb +0 -0
  333. data/lib/openc3/tools/table_manager/table_manager_core.rb +0 -0
  334. data/lib/openc3/tools/table_manager/table_parser.rb +0 -0
  335. data/lib/openc3/tools/test_runner/test.rb +0 -0
  336. data/lib/openc3/top_level.rb +1 -1
  337. data/lib/openc3/topics/autonomic_topic.rb +0 -0
  338. data/lib/openc3/topics/calendar_topic.rb +0 -0
  339. data/lib/openc3/topics/command_decom_topic.rb +0 -0
  340. data/lib/openc3/topics/command_topic.rb +0 -0
  341. data/lib/openc3/topics/config_topic.rb +0 -0
  342. data/lib/openc3/topics/decom_interface_topic.rb +2 -1
  343. data/lib/openc3/topics/interface_topic.rb +8 -2
  344. data/lib/openc3/topics/limits_event_topic.rb +0 -0
  345. data/lib/openc3/topics/notebook_topic.rb +0 -0
  346. data/lib/openc3/topics/queue_topic.rb +0 -0
  347. data/lib/openc3/topics/router_topic.rb +6 -1
  348. data/lib/openc3/topics/system_events_topic.rb +0 -0
  349. data/lib/openc3/topics/telemetry_decom_topic.rb +0 -0
  350. data/lib/openc3/topics/telemetry_topic.rb +0 -0
  351. data/lib/openc3/topics/timeline_topic.rb +0 -0
  352. data/lib/openc3/topics/topic.rb +0 -0
  353. data/lib/openc3/utilities/authentication.rb +4 -4
  354. data/lib/openc3/utilities/authorization.rb +0 -0
  355. data/lib/openc3/utilities/aws_bucket.rb +2 -2
  356. data/lib/openc3/utilities/bucket.rb +1 -1
  357. data/lib/openc3/utilities/bucket_file_cache.rb +55 -22
  358. data/lib/openc3/utilities/bucket_require.rb +0 -0
  359. data/lib/openc3/utilities/bucket_utilities.rb +3 -4
  360. data/lib/openc3/utilities/cli_generator.rb +0 -0
  361. data/lib/openc3/utilities/cmd_log.rb +0 -0
  362. data/lib/openc3/utilities/config_overlay.rb +75 -0
  363. data/lib/openc3/utilities/cosmos_rails_formatter.rb +0 -0
  364. data/lib/openc3/utilities/crc.rb +59 -32
  365. data/lib/openc3/utilities/csv.rb +0 -0
  366. data/lib/openc3/utilities/ctrf.rb +0 -0
  367. data/lib/openc3/utilities/env_helper.rb +0 -0
  368. data/lib/openc3/utilities/local_bucket.rb +0 -0
  369. data/lib/openc3/utilities/local_mode.rb +32 -6
  370. data/lib/openc3/utilities/logger.rb +30 -8
  371. data/lib/openc3/utilities/message_log.rb +0 -0
  372. data/lib/openc3/utilities/metric.rb +0 -0
  373. data/lib/openc3/utilities/migration.rb +0 -0
  374. data/lib/openc3/utilities/open_telemetry.rb +0 -0
  375. data/lib/openc3/utilities/process_manager.rb +0 -0
  376. data/lib/openc3/utilities/pypi_url.rb +0 -0
  377. data/lib/openc3/utilities/python_proxy.rb +0 -0
  378. data/lib/openc3/utilities/python_venv.rb +135 -0
  379. data/lib/openc3/utilities/quaternion.rb +0 -0
  380. data/lib/openc3/utilities/questdb_client.rb +29 -46
  381. data/lib/openc3/utilities/redis_secrets.rb +0 -0
  382. data/lib/openc3/utilities/reingest_job.rb +0 -0
  383. data/lib/openc3/utilities/ruby_lex_utils.rb +0 -0
  384. data/lib/openc3/utilities/rubygems_url.rb +39 -0
  385. data/lib/openc3/utilities/running_script.rb +24 -55
  386. data/lib/openc3/utilities/s3_autoload.rb +5 -5
  387. data/lib/openc3/utilities/script.rb +12 -8
  388. data/lib/openc3/utilities/secrets.rb +48 -3
  389. data/lib/openc3/utilities/simulated_target.rb +0 -0
  390. data/lib/openc3/utilities/sleeper.rb +0 -0
  391. data/lib/openc3/utilities/store.rb +0 -0
  392. data/lib/openc3/utilities/store_autoload.rb +2 -2
  393. data/lib/openc3/utilities/store_queued.rb +0 -0
  394. data/lib/openc3/utilities/target_file.rb +18 -1
  395. data/lib/openc3/utilities/thread_manager.rb +0 -0
  396. data/lib/openc3/utilities/throttle.rb +0 -0
  397. data/lib/openc3/utilities/zip.rb +0 -0
  398. data/lib/openc3/utilities.rb +0 -0
  399. data/lib/openc3/version.rb +6 -6
  400. data/lib/openc3/win32/excel.rb +0 -0
  401. data/lib/openc3/win32/win32.rb +0 -0
  402. data/lib/openc3/win32/win32_main.rb +0 -0
  403. data/lib/openc3.rb +2 -2
  404. data/tasks/gemfile_stats.rake +0 -0
  405. data/tasks/spec.rake +0 -0
  406. data/templates/command_validator/command_validator.py +0 -0
  407. data/templates/command_validator/command_validator.rb +0 -0
  408. data/templates/conversion/conversion.py +0 -0
  409. data/templates/conversion/conversion.rb +0 -0
  410. data/templates/limits_response/response.py +0 -0
  411. data/templates/limits_response/response.rb +0 -0
  412. data/templates/microservice/microservices/TEMPLATE/microservice.py +0 -0
  413. data/templates/microservice/microservices/TEMPLATE/microservice.rb +0 -0
  414. data/templates/plugin/.gitignore +0 -0
  415. data/templates/plugin/LICENSE.md +0 -0
  416. data/templates/plugin/README.md +0 -0
  417. data/templates/plugin/Rakefile +0 -0
  418. data/templates/plugin/plugin.gemspec +0 -0
  419. data/templates/plugin/plugin.txt +0 -0
  420. data/templates/processor/processor.py +1 -1
  421. data/templates/processor/processor.rb +0 -0
  422. data/templates/target/targets/TARGET/cmd_tlm/cmd.txt +0 -0
  423. data/templates/target/targets/TARGET/cmd_tlm/tlm.txt +0 -0
  424. data/templates/target/targets/TARGET/lib/target.py +0 -0
  425. data/templates/target/targets/TARGET/lib/target.rb +0 -0
  426. data/templates/target/targets/TARGET/procedures/procedure.py +0 -0
  427. data/templates/target/targets/TARGET/procedures/procedure.rb +0 -0
  428. data/templates/target/targets/TARGET/public/README.txt +0 -0
  429. data/templates/target/targets/TARGET/screens/status.txt +0 -0
  430. data/templates/target/targets/TARGET/target.txt +0 -0
  431. data/templates/tool_angular/.editorconfig +0 -0
  432. data/templates/tool_angular/.gitignore +0 -0
  433. data/templates/tool_angular/.vscode/extensions.json +0 -0
  434. data/templates/tool_angular/.vscode/launch.json +0 -0
  435. data/templates/tool_angular/.vscode/tasks.json +0 -0
  436. data/templates/tool_angular/angular.json +0 -0
  437. data/templates/tool_angular/extra-webpack.config.js +0 -0
  438. data/templates/tool_angular/package.json +2 -2
  439. data/templates/tool_angular/src/app/app-routing.module.ts +0 -0
  440. data/templates/tool_angular/src/app/app.component.html +0 -0
  441. data/templates/tool_angular/src/app/app.component.scss +0 -0
  442. data/templates/tool_angular/src/app/app.component.spec.ts +0 -0
  443. data/templates/tool_angular/src/app/app.component.ts +0 -0
  444. data/templates/tool_angular/src/app/app.module.ts +0 -0
  445. data/templates/tool_angular/src/app/custom-overlay-container.ts +0 -0
  446. data/templates/tool_angular/src/app/empty-route/empty-route.component.ts +0 -0
  447. data/templates/tool_angular/src/app/openc3-api.d.ts +0 -0
  448. data/templates/tool_angular/src/assets/.gitkeep +0 -0
  449. data/templates/tool_angular/src/environments/environment.prod.ts +0 -0
  450. data/templates/tool_angular/src/environments/environment.ts +0 -0
  451. data/templates/tool_angular/src/favicon.ico +0 -0
  452. data/templates/tool_angular/src/index.html +0 -0
  453. data/templates/tool_angular/src/main.single-spa.ts +0 -0
  454. data/templates/tool_angular/src/single-spa/asset-url.ts +0 -0
  455. data/templates/tool_angular/src/single-spa/single-spa-props.ts +0 -0
  456. data/templates/tool_angular/src/styles.scss +0 -0
  457. data/templates/tool_angular/tsconfig.app.json +0 -0
  458. data/templates/tool_angular/tsconfig.json +0 -0
  459. data/templates/tool_angular/tsconfig.spec.json +0 -0
  460. data/templates/tool_react/.eslintrc +0 -0
  461. data/templates/tool_react/.gitignore +0 -0
  462. data/templates/tool_react/.prettierignore +0 -0
  463. data/templates/tool_react/babel.config.json +0 -0
  464. data/templates/tool_react/jest.config.js +0 -0
  465. data/templates/tool_react/package.json +1 -1
  466. data/templates/tool_react/src/openc3-tool_name.js +0 -0
  467. data/templates/tool_react/src/root.component.js +0 -0
  468. data/templates/tool_react/src/root.component.test.js +0 -0
  469. data/templates/tool_react/webpack.config.js +0 -0
  470. data/templates/tool_svelte/.gitignore +0 -0
  471. data/templates/tool_svelte/.prettierignore +0 -0
  472. data/templates/tool_svelte/.prettierrc.js +0 -0
  473. data/templates/tool_svelte/babel.config.js +0 -0
  474. data/templates/tool_svelte/build/smui.css +0 -0
  475. data/templates/tool_svelte/jest.config.js +0 -0
  476. data/templates/tool_svelte/package.json +1 -1
  477. data/templates/tool_svelte/rollup.config.js +0 -0
  478. data/templates/tool_svelte/src/App.svelte +0 -0
  479. data/templates/tool_svelte/src/App.test.js +0 -0
  480. data/templates/tool_svelte/src/theme/_smui-theme.scss +0 -0
  481. data/templates/tool_svelte/src/tool_name.js +0 -0
  482. data/templates/tool_vue/.env.standalone +0 -0
  483. data/templates/tool_vue/.gitignore +0 -0
  484. data/templates/tool_vue/.prettierrc.cjs +0 -0
  485. data/templates/tool_vue/eslint.config.mjs +0 -0
  486. data/templates/tool_vue/jsconfig.json +0 -0
  487. data/templates/tool_vue/package.json +3 -3
  488. data/templates/tool_vue/src/App.vue +0 -0
  489. data/templates/tool_vue/src/main.js +0 -0
  490. data/templates/tool_vue/src/router.js +0 -0
  491. data/templates/tool_vue/src/tools/tool_name/tool_name.vue +0 -0
  492. data/templates/tool_vue/vite.config.js +1 -1
  493. data/templates/widget/.prettierrc.cjs +0 -0
  494. data/templates/widget/LICENSE.md +0 -0
  495. data/templates/widget/Rakefile +0 -0
  496. data/templates/widget/package.json +2 -2
  497. data/templates/widget/src/Widget.vue +0 -0
  498. data/templates/widget/vite.config.js +0 -0
  499. metadata +56 -9
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/lib/openc3/ext/.keep CHANGED
File without changes
File without changes
File without changes
File without changes
@@ -15,6 +15,7 @@
15
15
  # This file may also be used under the terms of a commercial license
16
16
  # if purchased from OpenC3, Inc.
17
17
 
18
+ require 'openc3/packets/packet'
18
19
  require 'openc3/api/api'
19
20
  require 'openc3/logs/stream_log_pair'
20
21
  require 'openc3/utilities/secrets'
@@ -433,8 +434,8 @@ module OpenC3
433
434
  config['name'] = @name
434
435
  config['state'] = @state
435
436
  config['clients'] = self.num_clients
436
- config['txsize'] = @write_queue_size
437
- config['rxsize'] = @read_queue_size
437
+ config['txsize'] = self.write_queue_size
438
+ config['rxsize'] = self.read_queue_size
438
439
  config['txbytes'] = @bytes_written
439
440
  config['rxbytes'] = @bytes_read
440
441
  config['txcnt'] = @write_count
@@ -677,12 +678,12 @@ module OpenC3
677
678
  result['read_raw_data'] = @read_raw_data
678
679
  result['written_raw_data'] = @written_raw_data
679
680
  if @read_raw_data_time
680
- result['read_raw_data_time'] = @read_raw_data_time.iso8601
681
+ result['read_raw_data_time'] = @read_raw_data_time.getutc.iso8601(6)
681
682
  else
682
683
  result['read_raw_data_time'] = nil
683
684
  end
684
685
  if @written_raw_data_time
685
- result['written_raw_data_time'] = @written_raw_data_time.iso8601
686
+ result['written_raw_data_time'] = @written_raw_data_time.getutc.iso8601(6)
686
687
  else
687
688
  result['written_raw_data_time'] = nil
688
689
  end
File without changes
@@ -49,6 +49,8 @@ module OpenC3
49
49
 
50
50
  # Creates a new {SerialStream} using the parameters passed in the constructor
51
51
  def connect
52
+ # Cleanly close any existing stream rather than leaving it open
53
+ @stream.disconnect if @stream
52
54
  @stream = MqttStream.new(@hostname, @port, @ssl, @write_topic, @read_topic, @ack_timeout)
53
55
  @stream.username = @username if @username
54
56
  @stream.password = @password if @password
@@ -23,6 +23,14 @@ module OpenC3
23
23
  # Reads all data available on the interface and creates a packet
24
24
  # with that data.
25
25
  class BurstProtocol < Protocol
26
+ # Maximum number of bytes which will be buffered while waiting for a
27
+ # complete packet. This bounds the memory a peer can cause the interface
28
+ # to allocate by declaring an enormous packet length (LENGTH, PREIDENTIFIED)
29
+ # or by never sending a terminator (TERMINATED). Deliberately much larger
30
+ # than any realistic packet so it does not affect existing configurations.
31
+ # Override with the OPENC3_PROTOCOL_MAX_BUFFER_SIZE environment variable.
32
+ DEFAULT_MAX_BUFFER_SIZE = 100_000_000
33
+
26
34
  # @param discard_leading_bytes [Integer] The number of bytes to discard
27
35
  # from the binary data after reading. Note that this is often
28
36
  # used to remove a sync pattern from the final packet data.
@@ -37,6 +45,7 @@ module OpenC3
37
45
  @sync_pattern = ConfigParser.handle_nil(sync_pattern)
38
46
  @sync_pattern = @sync_pattern.hex_to_byte_string if @sync_pattern
39
47
  @fill_fields = ConfigParser.handle_true_false(fill_fields)
48
+ @max_buffer_size = Integer(ENV.fetch('OPENC3_PROTOCOL_MAX_BUFFER_SIZE', DEFAULT_MAX_BUFFER_SIZE))
40
49
  end
41
50
 
42
51
  def reset
@@ -60,6 +69,7 @@ module OpenC3
60
69
  # @return [String|nil] Data for a packet consisting of the bytes read
61
70
  def read_data(data, extra = nil)
62
71
  @data << data
72
+ check_buffer_size()
63
73
  @extra = extra unless (data.length == 0 and extra.nil?) # Maintain extra from last read read_data
64
74
 
65
75
  while true
@@ -192,6 +202,21 @@ module OpenC3
192
202
  return super(data, extra)
193
203
  end
194
204
 
205
+ # Raises if the accumulation buffer has grown past @max_buffer_size. Called
206
+ # from read_data by both the Ruby and the C implementations. Raising causes
207
+ # Interface#read to log the error and disconnect, which drops the offending
208
+ # peer and resets this protocol.
209
+ def check_buffer_size
210
+ length = @data.length
211
+ return if length <= @max_buffer_size
212
+
213
+ # Release the buffer and clear any partially reduced state now rather than
214
+ # waiting for the interface to disconnect and reset() us
215
+ reset()
216
+ raise "#{@interface ? @interface.name : ""}: Protocol buffer of #{length} bytes exceeds maximum of #{@max_buffer_size} bytes. " \
217
+ "Increase OPENC3_PROTOCOL_MAX_BUFFER_SIZE."
218
+ end
219
+
195
220
  def log_discard(length, found)
196
221
  Logger.error("#{@interface ? @interface.name : ""}: Sync #{'not ' unless found}found. Discarding #{length} bytes of data.")
197
222
  if @data.length >= 0
@@ -210,6 +235,7 @@ module OpenC3
210
235
  result['discard_leading_bytes'] = @discard_leading_bytes
211
236
  result['sync_pattern'] = @sync_pattern.inspect
212
237
  result['fill_fields'] = @fill_fields
238
+ result['max_buffer_size'] = @max_buffer_size
213
239
  return result
214
240
  end
215
241
 
@@ -218,6 +244,7 @@ module OpenC3
218
244
  result['discard_leading_bytes'] = @discard_leading_bytes
219
245
  result['sync_pattern'] = @sync_pattern.inspect
220
246
  result['fill_fields'] = @fill_fields
247
+ result['max_buffer_size'] = @max_buffer_size
221
248
  return result
222
249
  end
223
250
  end
File without changes
File without changes
File without changes
@@ -168,6 +168,13 @@ module OpenC3
168
168
  raise "Length value received larger than max_length: #{length} > #{@max_length}" if @max_length and length > @max_length
169
169
 
170
170
  packet_length = (length * @length_bytes_per_count) + @length_value_offset
171
+ # Reject up front rather than buffering the declared number of bytes first
172
+ if packet_length > @max_buffer_size
173
+ reset() # Drop the partial frame rather than holding it until disconnect
174
+ raise "Calculated packet length of #{packet_length} bytes exceeds maximum buffer size of #{@max_buffer_size} bytes. " \
175
+ "Increase OPENC3_PROTOCOL_MAX_BUFFER_SIZE."
176
+ end
177
+
171
178
  # Ensure the calculated packet length is long enough to support the location of the length field
172
179
  # without overlap into the next packet
173
180
  if (packet_length * 8) < (@length_bit_offset + @length_bit_size)
@@ -106,6 +106,13 @@ module OpenC3
106
106
  when 4
107
107
  string_length = string_length.unpack('N')[0] # UINT32
108
108
  raise "Length value received larger than max_length: #{string_length} > #{@max_length}" if @max_length and string_length > @max_length
109
+
110
+ # Reject up front rather than buffering the declared number of bytes first
111
+ if string_length > @max_buffer_size
112
+ reset() # Drop the partial frame rather than holding it until disconnect
113
+ raise "Length value received of #{string_length} bytes exceeds maximum buffer size of #{@max_buffer_size} bytes. " \
114
+ "Increase OPENC3_PROTOCOL_MAX_BUFFER_SIZE."
115
+ end
109
116
  else
110
117
  raise "Unsupported length given to read_length_field_followed_by_string: #{length_num_bytes}"
111
118
  end
@@ -36,6 +36,14 @@ module OpenC3
36
36
  end
37
37
 
38
38
  def reset
39
+ @read_data_input_time = nil
40
+ @read_data_input = ''
41
+ @read_data_output_time = nil
42
+ @read_data_output = ''
43
+ @write_data_input_time = nil
44
+ @write_data_input = ''
45
+ @write_data_output_time = nil
46
+ @write_data_output = ''
39
47
  @extra = nil
40
48
  end
41
49
 
@@ -131,13 +139,13 @@ module OpenC3
131
139
  def write_details
132
140
  result = {'name' => self.class.name.to_s.split("::")[-1]}
133
141
  if @write_data_input_time
134
- result['write_data_input_time'] = @write_data_input_time.iso8601
142
+ result['write_data_input_time'] = @write_data_input_time.getutc.iso8601(6)
135
143
  else
136
144
  result['write_data_input_time'] = nil
137
145
  end
138
146
  result['write_data_input'] = @write_data_input
139
147
  if @write_data_output_time
140
- result['write_data_output_time'] = @write_data_output_time.iso8601
148
+ result['write_data_output_time'] = @write_data_output_time.getutc.iso8601(6)
141
149
  else
142
150
  result['write_data_output_time'] = nil
143
151
  end
@@ -148,13 +156,13 @@ module OpenC3
148
156
  def read_details
149
157
  result = {'name' => self.class.name.to_s.split("::")[-1]}
150
158
  if @read_data_input_time
151
- result['read_data_input_time'] = @read_data_input_time.iso8601
159
+ result['read_data_input_time'] = @read_data_input_time.getutc.iso8601(6)
152
160
  else
153
161
  result['read_data_input_time'] = nil
154
162
  end
155
163
  result['read_data_input'] = @read_data_input
156
164
  if @read_data_output_time
157
- result['read_data_output_time'] = @read_data_output_time.iso8601
165
+ result['read_data_output_time'] = @read_data_output_time.getutc.iso8601(6)
158
166
  else
159
167
  result['read_data_output_time'] = nil
160
168
  end
File without changes
@@ -266,7 +266,7 @@ module OpenC3
266
266
  result['response_timeout'] = @response_timeout
267
267
  result['response_polling_period'] = @response_polling_period
268
268
  if @connect_complete_time
269
- result['connect_complete_time'] = @connect_complete_time.iso8601
269
+ result['connect_complete_time'] = @connect_complete_time.getutc.iso8601(6)
270
270
  else
271
271
  result['connect_complete_time'] = nil
272
272
  end
@@ -285,7 +285,7 @@ module OpenC3
285
285
  result['response_timeout'] = @response_timeout
286
286
  result['response_polling_period'] = @response_polling_period
287
287
  if @connect_complete_time
288
- result['connect_complete_time'] = @connect_complete_time.iso8601
288
+ result['connect_complete_time'] = @connect_complete_time.getutc.iso8601(6)
289
289
  else
290
290
  result['connect_complete_time'] = nil
291
291
  end
@@ -77,6 +77,8 @@ module OpenC3
77
77
 
78
78
  # Creates a new {SerialStream} using the parameters passed in the constructor
79
79
  def connect
80
+ # Cleanly close any existing stream rather than leaving it open
81
+ @stream.disconnect if @stream
80
82
  @stream = SerialStream.new(
81
83
  @write_port_name,
82
84
  @read_port_name,
File without changes
File without changes
@@ -76,6 +76,8 @@ module OpenC3
76
76
  # Connects the {TcpipClientStream} by passing the
77
77
  # initialization parameters to the {TcpipClientStream}.
78
78
  def connect
79
+ # Cleanly close any existing stream rather than leaving it open
80
+ @stream.disconnect if @stream
79
81
  @stream = TcpipClientStream.new(
80
82
  @hostname,
81
83
  @write_port,
File without changes
@@ -23,6 +23,7 @@ module OpenC3
23
23
  # Base class for interfaces that send and receive messages over UDP
24
24
  class UdpInterface < Interface
25
25
  HOST_127_0_0_1 = '127.0.0.1'
26
+ HOST_0_0_0_0 = '0.0.0.0'
26
27
 
27
28
  # @param hostname [String] Machine to connect to
28
29
  # @param write_dest_port [Integer] Port to write commands to
@@ -77,8 +78,11 @@ module OpenC3
77
78
  @read_timeout = ConfigParser.handle_nil(read_timeout)
78
79
  @read_timeout = @read_timeout.to_f if @read_timeout
79
80
  @bind_address = ConfigParser.handle_nil(bind_address)
80
- if @bind_address && @bind_address.casecmp('LOCALHOST').zero?
81
- @bind_address = HOST_127_0_0_1
81
+ if @bind_address
82
+ @bind_address = HOST_127_0_0_1 if @bind_address.casecmp('LOCALHOST').zero?
83
+ else
84
+ # nil means all local addresses which is what 0.0.0.0 means
85
+ @bind_address = HOST_0_0_0_0
82
86
  end
83
87
  @write_socket = nil
84
88
  @read_socket = nil
@@ -91,9 +95,9 @@ module OpenC3
91
95
  result = ''
92
96
  result += " #{@hostname}:#{@write_dest_port} (write dest port)" if @write_dest_port
93
97
  result += " #{@write_src_port} (write src port)" if @write_src_port
94
- result += " #{@hostname}:#{@read_port} (read)" if @read_port
98
+ result += " #{@bind_address}:#{@read_port} (read)" if @read_port
95
99
  result += " #{@interface_address} (interface addr)" if @interface_address
96
- result += " #{@bind_address} (bind addr)" if @bind_address != '0.0.0.0'
100
+ result += " #{@bind_address} (bind addr)" if @bind_address != HOST_0_0_0_0
97
101
  return result.strip
98
102
  end
99
103
 
@@ -102,13 +106,20 @@ module OpenC3
102
106
  # the constructor.
103
107
  def connect
104
108
  if @read_port and @write_dest_port and @write_src_port and (@read_port == @write_src_port)
109
+ # read_multicast is false because this socket is not connected and thus
110
+ # doesn't filter by peer address. Joining the multicast group we write to
111
+ # would deliver our own commands back to us as telemetry (multicast
112
+ # loopback is enabled by default).
105
113
  @read_socket = UdpReadWriteSocket.new(
106
114
  @read_port,
107
115
  @bind_address,
108
116
  @write_dest_port,
109
117
  @hostname,
110
118
  @interface_address,
111
- @ttl
119
+ @ttl,
120
+ false, # read_multicast
121
+ true, # write_multicast
122
+ false # connect_socket
112
123
  )
113
124
  @write_socket = @read_socket
114
125
  else
File without changes
File without changes
File without changes
@@ -35,8 +35,9 @@ module OpenC3
35
35
  # pull openc3-cosmos-script-runner-api url from environment variables
36
36
  def _generate_url(microservice_name:, prefix:, schema: 'http', hostname: nil, port:, scope: $openc3_scope)
37
37
  prefix = '/' + prefix unless prefix[0] == '/'
38
- if ENV['OPENC3_OPERATOR_HOSTNAME']
39
- hostname = ENV['OPENC3_OPERATOR_HOSTNAME'] unless hostname
38
+ operator_hostname = ENV.fetch('OPENC3_OPERATOR_HOSTNAME', nil)
39
+ if operator_hostname
40
+ hostname = operator_hostname unless hostname
40
41
  return "#{schema}://#{hostname}:#{port.to_i}#{prefix}"
41
42
  else
42
43
  if ENV['KUBERNETES_SERVICE_HOST']
@@ -53,10 +53,19 @@ module OpenC3
53
53
 
54
54
  USER_AGENT = 'OpenC3 / v7 (ruby/openc3/lib/io/json_api_object)'.freeze
55
55
 
56
+ # Time limit for the first response byte from the server. This must be an
57
+ # explicit number rather than nil, see connect() for why. Requests can
58
+ # legitimately block for a long time, e.g. cmd() with a large timeout waiting
59
+ # on an interface ack, so this is effectively "wait forever" while still
60
+ # bounded so a wedged connection eventually releases the thread.
61
+ DEFAULT_READ_TIMEOUT_S = 86400
62
+
56
63
  # @param url [String] The url of openc3-cosmos-cmd-tlm-api http://openc3-cosmos-cmd-tlm-api:2901
57
64
  # @param timeout [Float] The time to wait before disconnecting 1.0
58
65
  # @param authentication [OpenC3Authentication] The authentication object if nill initialize will generate
59
- def initialize(url:, timeout: 1.0, authentication: nil)
66
+ # @param read_timeout [Float] The time to wait for the first response byte from the server.
67
+ # Defaults to the OPENC3_API_READ_TIMEOUT environment variable or DEFAULT_READ_TIMEOUT_S.
68
+ def initialize(url:, timeout: 1.0, authentication: nil, read_timeout: nil)
60
69
  @http = nil
61
70
  @mutex = Mutex.new
62
71
  @request_data = ""
@@ -65,6 +74,7 @@ module OpenC3
65
74
  @log = [nil, nil, nil]
66
75
  @authentication = authentication.nil? ? generate_auth() : authentication
67
76
  @timeout = timeout
77
+ @read_timeout = (read_timeout || ENV.fetch('OPENC3_API_READ_TIMEOUT', DEFAULT_READ_TIMEOUT_S)).to_f
68
78
  @shutdown = false
69
79
  # JsonDRb.debug = true # Enable for debugging
70
80
  end
@@ -120,7 +130,11 @@ module OpenC3
120
130
  # :open_timeout - time limit for just the connection phase (e.g. handshake) (Integer in seconds)
121
131
  # :read_timeout - time limit for the first response byte received from the server (Integer in seconds)
122
132
  # :write_timeout - time limit for the client to send the request to the server (Integer in seconds)
123
- @http = Faraday.new(request: { open_timeout: @timeout.to_i, read_timeout: nil }) do |f|
133
+ # NOTE: read_timeout must be an explicit number. Faraday only assigns it to Net::HTTP
134
+ # when the value is truthy (see Faraday::Adapter::NetHttp#configure_request), so passing
135
+ # nil does NOT mean "wait forever", it silently leaves Net::HTTP's 60s default in place.
136
+ # That 60s then caps every request regardless of any longer application level timeout.
137
+ @http = Faraday.new(request: { open_timeout: @timeout.to_i, read_timeout: @read_timeout }) do |f|
124
138
  f.adapter :net_http # adds the adapter to the connection, defaults to `Faraday.default_adapter`
125
139
  end
126
140
  rescue => e
@@ -212,7 +226,9 @@ module OpenC3
212
226
  @response_data = resp.body
213
227
  return resp
214
228
  rescue Faraday::ConnectionFailed, Errno::ECONNRESET, Errno::EPIPE, IOError => e
215
- # Connection errors are retryable - reconnect and try again
229
+ # Retryable. Nothing was successfully sent, so replaying is safe. This includes
230
+ # Net::OpenTimeout, which Faraday maps to ConnectionFailed and which covers a
231
+ # service that is still starting up.
216
232
  retry_count += 1
217
233
  @log[2] = "#{method} Exception: #{e.class}, #{e.message}, #{e.backtrace}"
218
234
  if retry_count <= RETRY_COUNT
@@ -225,6 +241,11 @@ module OpenC3
225
241
  raise error
226
242
  end
227
243
  rescue StandardError => e
244
+ # Everything else, including Faraday::TimeoutError from a read timeout, is NOT
245
+ # retryable. A read timeout means the request was fully sent and the server may
246
+ # have already acted on it. Many endpoints are not idempotent (create_activity,
247
+ # script_run, cmd), so a retry risks duplicating the operation. It would also blow
248
+ # past the caller's deadline by RETRY_COUNT times.
228
249
  @log[2] = "#{method} Exception: #{e.class}, #{e.message}, #{e.backtrace}"
229
250
  disconnect()
230
251
  error = "Api Exception: #{@log[0]} ::: #{@log[1]} ::: #{@log[2]}"
@@ -282,10 +282,26 @@ module OpenC3
282
282
  response = JsonRpcSuccessResponse.new(result, request.id)
283
283
  end
284
284
  rescue Exception => e
285
- # Filter out the framework stack trace (rails, rack, puma etc)
286
- lines = e.formatted.split("\n")
287
- i = lines.find_index { |row| row.include?('actionpack') || row.include?('activesupport') }
288
- Logger.error lines[0...i].join("\n")
285
+ error_name = e.class.name.split('::')[-1]
286
+ method_name = request.method.downcase()
287
+ case e
288
+ when AuthError, ForbiddenError
289
+ # Auth failures are expected (e.g. browser requests before login or with an
290
+ # expired session token) so log a single line without the stack trace
291
+ Logger.warn "#{error_name} : #{e.message} calling #{method_name}"
292
+ when HazardousError, CriticalCmdError
293
+ # Not errors at all: these are the signal that the UI should raise an
294
+ # operator confirmation dialog, and the user retries with the hazardous
295
+ # or critical flag set. A stack trace per prompt is pure noise, and
296
+ # HazardousError#to_s embeds the formatted command with a newline,
297
+ # so log just the error name and the method that raised it.
298
+ Logger.info "#{error_name} calling #{method_name}"
299
+ else
300
+ # Filter out the framework stack trace (rails, rack, puma etc)
301
+ lines = e.formatted.split("\n")
302
+ i = lines.find_index { |row| row.include?('actionpack') || row.include?('activesupport') }
303
+ Logger.error lines[0...(i || lines.length)].join("\n")
304
+ end
289
305
 
290
306
  if request.id
291
307
  if NoMethodError === e
@@ -38,8 +38,9 @@ module OpenC3
38
38
  # @param url [String] The url of openc3-cosmos-cmd-tlm-api http://openc3-cosmos-cmd-tlm-api:2901
39
39
  # @param timeout [Float] The time to wait before disconnecting 1.0
40
40
  # @param authentication [OpenC3Authentication] The authentication object if nill initialize will generate
41
- def initialize(url:, timeout: 1.0, authentication: nil)
42
- super(url: url, timeout: timeout, authentication: authentication)
41
+ # @param read_timeout [Float] The time to wait for the first response byte from the server
42
+ def initialize(url:, timeout: 1.0, authentication: nil, read_timeout: nil)
43
+ super(url: url, timeout: timeout, authentication: authentication, read_timeout: read_timeout)
43
44
  @uri = URI("#{url}/openc3-api/api")
44
45
  end
45
46
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes