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.
- checksums.yaml +7 -0
- data/Gemfile +18 -0
- data/Guardfile +35 -0
- data/LICENSE.txt +727 -0
- data/README.md +37 -0
- data/Rakefile +131 -0
- data/bin/cstol_converter +1178 -0
- data/bin/openc3cli +531 -0
- data/bin/rubysloc +139 -0
- data/data/config/_array_params.yaml +23 -0
- data/data/config/_id_items.yaml +24 -0
- data/data/config/_id_params.yaml +58 -0
- data/data/config/_interfaces.yaml +214 -0
- data/data/config/_interfaces.yaml.err +1017 -0
- data/data/config/_items.yaml +20 -0
- data/data/config/_params.yaml +60 -0
- data/data/config/cmd_tlm_server.yaml +136 -0
- data/data/config/command.yaml +44 -0
- data/data/config/command_modifiers.yaml +160 -0
- data/data/config/command_telemetry.yaml +3 -0
- data/data/config/interface_modifiers.yaml +104 -0
- data/data/config/item_modifiers.yaml +221 -0
- data/data/config/microservice.yaml +78 -0
- data/data/config/param_item_modifiers.yaml +52 -0
- data/data/config/parameter_modifiers.yaml +200 -0
- data/data/config/plugins.yaml +80 -0
- data/data/config/protocols.yaml +290 -0
- data/data/config/screen.yaml +147 -0
- data/data/config/table_manager.yaml +89 -0
- data/data/config/table_parameter_modifiers.yaml +9 -0
- data/data/config/target.yaml +142 -0
- data/data/config/target_config.yaml +94 -0
- data/data/config/telemetry.yaml +87 -0
- data/data/config/telemetry_modifiers.yaml +159 -0
- data/data/config/tool.yaml +63 -0
- data/data/config/unknown.yaml +3 -0
- data/data/config/widgets.yaml +1505 -0
- data/ext/mkrf_conf.rb +49 -0
- data/ext/openc3/ext/array/array.c +122 -0
- data/ext/openc3/ext/array/extconf.rb +13 -0
- data/ext/openc3/ext/buffered_file/buffered_file.c +198 -0
- data/ext/openc3/ext/buffered_file/extconf.rb +13 -0
- data/ext/openc3/ext/config_parser/config_parser.c +280 -0
- data/ext/openc3/ext/config_parser/extconf.rb +13 -0
- data/ext/openc3/ext/crc/crc.c +351 -0
- data/ext/openc3/ext/crc/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/extconf.rb +13 -0
- data/ext/openc3/ext/openc3_io/openc3_io.c +158 -0
- data/ext/openc3/ext/packet/extconf.rb +13 -0
- data/ext/openc3/ext/packet/packet.c +318 -0
- data/ext/openc3/ext/platform/extconf.rb +13 -0
- data/ext/openc3/ext/platform/platform.c +134 -0
- data/ext/openc3/ext/polynomial_conversion/extconf.rb +13 -0
- data/ext/openc3/ext/polynomial_conversion/polynomial_conversion.c +79 -0
- data/ext/openc3/ext/string/extconf.rb +13 -0
- data/ext/openc3/ext/string/string.c +63 -0
- data/ext/openc3/ext/structure/structure.c +1719 -0
- data/ext/openc3/ext/tabbed_plots_config/extconf.rb +13 -0
- data/ext/openc3/ext/tabbed_plots_config/tabbed_plots_config.c +62 -0
- data/ext/openc3/ext/telemetry/extconf.rb +13 -0
- data/ext/openc3/ext/telemetry/telemetry.c +336 -0
- data/lib/cosmos.rb +20 -0
- data/lib/cosmosc2.rb +20 -0
- data/lib/openc3/api/api.rb +39 -0
- data/lib/openc3/api/authorized_api.rb +30 -0
- data/lib/openc3/api/cmd_api.rb +451 -0
- data/lib/openc3/api/config_api.rb +58 -0
- data/lib/openc3/api/interface_api.rb +117 -0
- data/lib/openc3/api/limits_api.rb +375 -0
- data/lib/openc3/api/router_api.rb +117 -0
- data/lib/openc3/api/settings_api.rb +70 -0
- data/lib/openc3/api/target_api.rb +78 -0
- data/lib/openc3/api/tlm_api.rb +455 -0
- data/lib/openc3/bridge/bridge.rb +54 -0
- data/lib/openc3/bridge/bridge_config.rb +167 -0
- data/lib/openc3/bridge/bridge_interface_thread.rb +42 -0
- data/lib/openc3/bridge/bridge_router_thread.rb +42 -0
- data/lib/openc3/ccsds/ccsds_packet.rb +68 -0
- data/lib/openc3/ccsds/ccsds_parser.rb +148 -0
- data/lib/openc3/config/config_parser.rb +549 -0
- data/lib/openc3/config/meta_config_parser.rb +74 -0
- data/lib/openc3/conversions/conversion.rb +70 -0
- data/lib/openc3/conversions/generic_conversion.rb +83 -0
- data/lib/openc3/conversions/packet_time_formatted_conversion.rb +43 -0
- data/lib/openc3/conversions/packet_time_seconds_conversion.rb +43 -0
- data/lib/openc3/conversions/polynomial_conversion.rb +87 -0
- data/lib/openc3/conversions/processor_conversion.rb +70 -0
- data/lib/openc3/conversions/received_count_conversion.rb +38 -0
- data/lib/openc3/conversions/received_time_formatted_conversion.rb +42 -0
- data/lib/openc3/conversions/received_time_seconds_conversion.rb +42 -0
- data/lib/openc3/conversions/segmented_polynomial_conversion.rb +171 -0
- data/lib/openc3/conversions/unix_time_conversion.rb +68 -0
- data/lib/openc3/conversions/unix_time_formatted_conversion.rb +49 -0
- data/lib/openc3/conversions/unix_time_seconds_conversion.rb +49 -0
- data/lib/openc3/conversions.rb +34 -0
- data/lib/openc3/core_ext/array.rb +416 -0
- data/lib/openc3/core_ext/binding.rb +29 -0
- data/lib/openc3/core_ext/class.rb +72 -0
- data/lib/openc3/core_ext/exception.rb +61 -0
- data/lib/openc3/core_ext/file.rb +83 -0
- data/lib/openc3/core_ext/hash.rb +37 -0
- data/lib/openc3/core_ext/io.rb +134 -0
- data/lib/openc3/core_ext/kernel.rb +42 -0
- data/lib/openc3/core_ext/math.rb +128 -0
- data/lib/openc3/core_ext/matrix.rb +156 -0
- data/lib/openc3/core_ext/objectspace.rb +36 -0
- data/lib/openc3/core_ext/openc3_io.rb +57 -0
- data/lib/openc3/core_ext/range.rb +27 -0
- data/lib/openc3/core_ext/socket.rb +38 -0
- data/lib/openc3/core_ext/string.rb +389 -0
- data/lib/openc3/core_ext/stringio.rb +33 -0
- data/lib/openc3/core_ext/time.rb +508 -0
- data/lib/openc3/core_ext.rb +36 -0
- data/lib/openc3/interfaces/interface.rb +498 -0
- data/lib/openc3/interfaces/linc_interface.rb +475 -0
- data/lib/openc3/interfaces/protocols/burst_protocol.rb +192 -0
- data/lib/openc3/interfaces/protocols/crc_protocol.rb +193 -0
- data/lib/openc3/interfaces/protocols/fixed_protocol.rb +155 -0
- data/lib/openc3/interfaces/protocols/ignore_packet_protocol.rb +56 -0
- data/lib/openc3/interfaces/protocols/length_protocol.rb +165 -0
- data/lib/openc3/interfaces/protocols/override_protocol.rb +60 -0
- data/lib/openc3/interfaces/protocols/preidentified_protocol.rb +206 -0
- data/lib/openc3/interfaces/protocols/protocol.rb +82 -0
- data/lib/openc3/interfaces/protocols/template_protocol.rb +261 -0
- data/lib/openc3/interfaces/protocols/terminated_protocol.rb +93 -0
- data/lib/openc3/interfaces/serial_interface.rb +94 -0
- data/lib/openc3/interfaces/simulated_target_interface.rb +168 -0
- data/lib/openc3/interfaces/stream_interface.rb +81 -0
- data/lib/openc3/interfaces/tcpip_client_interface.rb +69 -0
- data/lib/openc3/interfaces/tcpip_server_interface.rb +629 -0
- data/lib/openc3/interfaces/udp_interface.rb +169 -0
- data/lib/openc3/interfaces.rb +44 -0
- data/lib/openc3/io/buffered_file.rb +109 -0
- data/lib/openc3/io/io_multiplexer.rb +80 -0
- data/lib/openc3/io/json_api_object.rb +208 -0
- data/lib/openc3/io/json_drb.rb +335 -0
- data/lib/openc3/io/json_drb_object.rb +114 -0
- data/lib/openc3/io/json_drb_rack.rb +84 -0
- data/lib/openc3/io/json_rpc.rb +420 -0
- data/lib/openc3/io/openc3_snmp.rb +58 -0
- data/lib/openc3/io/posix_serial_driver.rb +156 -0
- data/lib/openc3/io/raw_logger.rb +167 -0
- data/lib/openc3/io/raw_logger_pair.rb +77 -0
- data/lib/openc3/io/serial_driver.rb +105 -0
- data/lib/openc3/io/stderr.rb +43 -0
- data/lib/openc3/io/stdout.rb +43 -0
- data/lib/openc3/io/udp_sockets.rb +194 -0
- data/lib/openc3/io/win32_serial_driver.rb +196 -0
- data/lib/openc3/logs/log_writer.rb +302 -0
- data/lib/openc3/logs/packet_log_constants.rb +62 -0
- data/lib/openc3/logs/packet_log_reader.rb +345 -0
- data/lib/openc3/logs/packet_log_writer.rb +299 -0
- data/lib/openc3/logs/text_log_writer.rb +68 -0
- data/lib/openc3/logs.rb +25 -0
- data/lib/openc3/microservices/cleanup_microservice.rb +68 -0
- data/lib/openc3/microservices/decom_microservice.rb +136 -0
- data/lib/openc3/microservices/interface_microservice.rb +532 -0
- data/lib/openc3/microservices/log_microservice.rb +108 -0
- data/lib/openc3/microservices/microservice.rb +204 -0
- data/lib/openc3/microservices/plugin_microservice.rb +43 -0
- data/lib/openc3/microservices/reaction_microservice.rb +541 -0
- data/lib/openc3/microservices/reducer_microservice.rb +313 -0
- data/lib/openc3/microservices/router_microservice.rb +44 -0
- data/lib/openc3/microservices/text_log_microservice.rb +84 -0
- data/lib/openc3/microservices/timeline_microservice.rb +363 -0
- data/lib/openc3/microservices/trigger_group_microservice.rb +638 -0
- data/lib/openc3/models/activity_model.rb +319 -0
- data/lib/openc3/models/auth_model.rb +65 -0
- data/lib/openc3/models/cvt_model.rb +185 -0
- data/lib/openc3/models/environment_model.rb +58 -0
- data/lib/openc3/models/gem_model.rb +137 -0
- data/lib/openc3/models/info_model.rb +31 -0
- data/lib/openc3/models/interface_model.rb +281 -0
- data/lib/openc3/models/interface_status_model.rb +117 -0
- data/lib/openc3/models/metadata_model.rb +139 -0
- data/lib/openc3/models/metric_model.rb +59 -0
- data/lib/openc3/models/microservice_model.rb +206 -0
- data/lib/openc3/models/microservice_status_model.rb +74 -0
- data/lib/openc3/models/model.rb +204 -0
- data/lib/openc3/models/note_model.rb +122 -0
- data/lib/openc3/models/notification_model.rb +40 -0
- data/lib/openc3/models/ping_model.rb +35 -0
- data/lib/openc3/models/plugin_model.rb +292 -0
- data/lib/openc3/models/process_status_model.rb +76 -0
- data/lib/openc3/models/reaction_model.rb +322 -0
- data/lib/openc3/models/reducer_model.rb +65 -0
- data/lib/openc3/models/router_model.rb +35 -0
- data/lib/openc3/models/router_status_model.rb +27 -0
- data/lib/openc3/models/scope_model.rb +153 -0
- data/lib/openc3/models/settings_model.rb +55 -0
- data/lib/openc3/models/sorted_model.rb +167 -0
- data/lib/openc3/models/target_model.rb +759 -0
- data/lib/openc3/models/timeline_model.rb +154 -0
- data/lib/openc3/models/tool_config_model.rb +38 -0
- data/lib/openc3/models/tool_model.rb +262 -0
- data/lib/openc3/models/trigger_group_model.rb +186 -0
- data/lib/openc3/models/trigger_model.rb +330 -0
- data/lib/openc3/models/widget_model.rb +138 -0
- data/lib/openc3/operators/microservice_operator.rb +128 -0
- data/lib/openc3/operators/operator.rb +277 -0
- data/lib/openc3/packets/binary_accessor.rb +1207 -0
- data/lib/openc3/packets/commands.rb +373 -0
- data/lib/openc3/packets/json_packet.rb +134 -0
- data/lib/openc3/packets/limits.rb +271 -0
- data/lib/openc3/packets/limits_response.rb +53 -0
- data/lib/openc3/packets/packet.rb +1168 -0
- data/lib/openc3/packets/packet_config.rb +625 -0
- data/lib/openc3/packets/packet_item.rb +586 -0
- data/lib/openc3/packets/packet_item_limits.rb +162 -0
- data/lib/openc3/packets/parsers/format_string_parser.rb +65 -0
- data/lib/openc3/packets/parsers/limits_parser.rb +159 -0
- data/lib/openc3/packets/parsers/limits_response_parser.rb +61 -0
- data/lib/openc3/packets/parsers/packet_item_parser.rb +272 -0
- data/lib/openc3/packets/parsers/packet_parser.rb +134 -0
- data/lib/openc3/packets/parsers/processor_parser.rb +73 -0
- data/lib/openc3/packets/parsers/state_parser.rb +127 -0
- data/lib/openc3/packets/parsers/xtce_converter.rb +442 -0
- data/lib/openc3/packets/parsers/xtce_parser.rb +722 -0
- data/lib/openc3/packets/structure.rb +553 -0
- data/lib/openc3/packets/structure_item.rb +365 -0
- data/lib/openc3/packets/telemetry.rb +487 -0
- data/lib/openc3/processors/processor.rb +86 -0
- data/lib/openc3/processors/statistics_processor.rb +82 -0
- data/lib/openc3/processors/watermark_processor.rb +58 -0
- data/lib/openc3/processors.rb +24 -0
- data/lib/openc3/script/api_shared.rb +828 -0
- data/lib/openc3/script/calendar.rb +89 -0
- data/lib/openc3/script/commands.rb +227 -0
- data/lib/openc3/script/exceptions.rb +29 -0
- data/lib/openc3/script/extract.rb +161 -0
- data/lib/openc3/script/limits.rb +60 -0
- data/lib/openc3/script/script.rb +299 -0
- data/lib/openc3/script/script_runner.rb +238 -0
- data/lib/openc3/script/storage.rb +146 -0
- data/lib/openc3/script/suite.rb +542 -0
- data/lib/openc3/script/suite_results.rb +196 -0
- data/lib/openc3/script/suite_runner.rb +217 -0
- data/lib/openc3/script.rb +21 -0
- data/lib/openc3/streams/serial_stream.rb +167 -0
- data/lib/openc3/streams/stream.rb +63 -0
- data/lib/openc3/streams/tcpip_client_stream.rb +116 -0
- data/lib/openc3/streams/tcpip_socket_stream.rb +195 -0
- data/lib/openc3/system/system.rb +127 -0
- data/lib/openc3/system/system_config.rb +411 -0
- data/lib/openc3/system/target.rb +269 -0
- data/lib/openc3/system.rb +24 -0
- data/lib/openc3/tools/cmd_tlm_server/api.rb +20 -0
- data/lib/openc3/tools/cmd_tlm_server/cmd_tlm_server_config.rb +320 -0
- data/lib/openc3/tools/cmd_tlm_server/interface_thread.rb +294 -0
- data/lib/openc3/tools/table_manager/table.rb +77 -0
- data/lib/openc3/tools/table_manager/table_config.rb +273 -0
- data/lib/openc3/tools/table_manager/table_item.rb +90 -0
- data/lib/openc3/tools/table_manager/table_item_parser.rb +66 -0
- data/lib/openc3/tools/table_manager/table_manager_core.rb +333 -0
- data/lib/openc3/tools/table_manager/table_parser.rb +93 -0
- data/lib/openc3/tools/test_runner/test.rb +67 -0
- data/lib/openc3/top_level.rb +595 -0
- data/lib/openc3/topics/autonomic_topic.rb +52 -0
- data/lib/openc3/topics/calendar_topic.rb +44 -0
- data/lib/openc3/topics/command_decom_topic.rb +76 -0
- data/lib/openc3/topics/command_topic.rb +83 -0
- data/lib/openc3/topics/config_topic.rb +68 -0
- data/lib/openc3/topics/interface_topic.rb +73 -0
- data/lib/openc3/topics/limits_event_topic.rb +109 -0
- data/lib/openc3/topics/notifications_topic.rb +28 -0
- data/lib/openc3/topics/router_topic.rb +85 -0
- data/lib/openc3/topics/telemetry_decom_topic.rb +54 -0
- data/lib/openc3/topics/telemetry_topic.rb +36 -0
- data/lib/openc3/topics/timeline_topic.rb +45 -0
- data/lib/openc3/topics/topic.rb +53 -0
- data/lib/openc3/utilities/authentication.rb +141 -0
- data/lib/openc3/utilities/authorization.rb +51 -0
- data/lib/openc3/utilities/crc.rb +278 -0
- data/lib/openc3/utilities/csv.rb +153 -0
- data/lib/openc3/utilities/logger.rb +187 -0
- data/lib/openc3/utilities/message_log.rb +91 -0
- data/lib/openc3/utilities/metric.rb +141 -0
- data/lib/openc3/utilities/process_manager.rb +139 -0
- data/lib/openc3/utilities/quaternion.rb +257 -0
- data/lib/openc3/utilities/ruby_lex_utils.rb +568 -0
- data/lib/openc3/utilities/s3.rb +202 -0
- data/lib/openc3/utilities/s3_autoload.rb +9 -0
- data/lib/openc3/utilities/s3_file_cache.rb +274 -0
- data/lib/openc3/utilities/simulated_target.rb +117 -0
- data/lib/openc3/utilities/sleeper.rb +51 -0
- data/lib/openc3/utilities/store.rb +23 -0
- data/lib/openc3/utilities/store_autoload.rb +237 -0
- data/lib/openc3/utilities/zip.rb +21 -0
- data/lib/openc3/utilities.rb +35 -0
- data/lib/openc3/version.rb +14 -0
- data/lib/openc3/win32/excel.rb +132 -0
- data/lib/openc3/win32/win32.rb +402 -0
- data/lib/openc3/win32/win32_main.rb +333 -0
- data/lib/openc3.rb +49 -0
- data/tasks/gemfile_stats.rake +113 -0
- data/tasks/spec.rake +30 -0
- data/templates/plugin-template/README.md +15 -0
- data/templates/plugin-template/Rakefile +12 -0
- data/templates/plugin-template/plugin.gemspec +23 -0
- data/templates/plugin-template/plugin.txt +9 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/cmd.txt +8 -0
- data/templates/plugin-template/targets/TARGET/cmd_tlm/tlm.txt +8 -0
- data/templates/plugin-template/targets/TARGET/lib/target.rb +10 -0
- data/templates/plugin-template/targets/TARGET/procedures/procedure.rb +3 -0
- data/templates/plugin-template/targets/TARGET/screens/status.txt +9 -0
- data/templates/plugin-template/targets/TARGET/target.txt +5 -0
- metadata +849 -0
|
@@ -0,0 +1,330 @@
|
|
|
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
|
+
require 'openc3/models/microservice_model'
|
|
22
|
+
require 'openc3/models/target_model'
|
|
23
|
+
require 'openc3/topics/autonomic_topic'
|
|
24
|
+
|
|
25
|
+
module OpenC3
|
|
26
|
+
class TriggerError < StandardError; end
|
|
27
|
+
|
|
28
|
+
class TriggerInputError < TriggerError; end
|
|
29
|
+
|
|
30
|
+
# INPUT:
|
|
31
|
+
# {
|
|
32
|
+
# "group": "someGroup",
|
|
33
|
+
# "left": {
|
|
34
|
+
# "type": "item",
|
|
35
|
+
# "target": "INST",
|
|
36
|
+
# "packet": "ADCS",
|
|
37
|
+
# "item": "POSX",
|
|
38
|
+
# },
|
|
39
|
+
# "operator": ">",
|
|
40
|
+
# "right": {
|
|
41
|
+
# "type": "value",
|
|
42
|
+
# "value": 690000,
|
|
43
|
+
# }
|
|
44
|
+
# }
|
|
45
|
+
class TriggerModel < Model
|
|
46
|
+
PRIMARY_KEY = '__TRIGGERS__'.freeze
|
|
47
|
+
ITEM_TYPE = 'item'.freeze
|
|
48
|
+
LIMIT_TYPE = 'limit'.freeze
|
|
49
|
+
FLOAT_TYPE = 'float'.freeze
|
|
50
|
+
STRING_TYPE = 'string'.freeze
|
|
51
|
+
TRIGGER_TYPE = 'trigger'.freeze
|
|
52
|
+
|
|
53
|
+
def self.create_mini_id
|
|
54
|
+
time = (Time.now.to_f * 10_000_000).to_i
|
|
55
|
+
jitter = rand(10_000_000)
|
|
56
|
+
key = "#{jitter}#{time}".to_i.to_s(36)
|
|
57
|
+
return "TV0-#{key}"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# @return [TriggerModel] Return the object with the name at
|
|
61
|
+
def self.get(name:, group:, scope:)
|
|
62
|
+
json = super("#{scope}#{PRIMARY_KEY}#{group}", name: name)
|
|
63
|
+
unless json.nil?
|
|
64
|
+
self.from_json(json, name: name, scope: scope)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# @return [Array<Hash>] All the Key, Values stored under the name key
|
|
69
|
+
def self.all(group:, scope:)
|
|
70
|
+
super("#{scope}#{PRIMARY_KEY}#{group}")
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @return [Array<String>] All the uuids stored under the name key
|
|
74
|
+
def self.names(group:, scope:)
|
|
75
|
+
super("#{scope}#{PRIMARY_KEY}#{group}")
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Check dependents before delete.
|
|
79
|
+
def self.delete(name:, group:, scope:)
|
|
80
|
+
model = self.get(name: name, group: group, scope: scope)
|
|
81
|
+
if model.nil?
|
|
82
|
+
raise TriggerInputError.new "invalid operation group: #{group} trigger: #{name} not found"
|
|
83
|
+
end
|
|
84
|
+
unless model.dependents.empty?
|
|
85
|
+
raise TriggerError.new "failed to delete #{name} dependents: #{model.dependents}"
|
|
86
|
+
end
|
|
87
|
+
model.roots.each do | trigger |
|
|
88
|
+
trigger_model = self.get(name: trigger, group: group, scope: scope)
|
|
89
|
+
trigger_model.update_dependents(dependent: name, remove: true)
|
|
90
|
+
trigger_model.update()
|
|
91
|
+
end
|
|
92
|
+
Store.hdel("#{scope}#{PRIMARY_KEY}#{group}", name)
|
|
93
|
+
model.notify(kind: 'deleted')
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def validate_operand(operand:)
|
|
97
|
+
unless operand.is_a?(Hash)
|
|
98
|
+
raise TriggerInputError.new "invalid operand: #{operand}"
|
|
99
|
+
end
|
|
100
|
+
operand_types = [ITEM_TYPE, LIMIT_TYPE, FLOAT_TYPE, STRING_TYPE, TRIGGER_TYPE]
|
|
101
|
+
unless operand_types.include?(operand['type'])
|
|
102
|
+
raise TriggerInputError.new "invalid operand type: #{operand['type']} must be of type: #{operand_types}"
|
|
103
|
+
end
|
|
104
|
+
if operand[operand['type']].nil?
|
|
105
|
+
raise TriggerInputError.new "invalid operand must contain type: #{operand}"
|
|
106
|
+
end
|
|
107
|
+
case operand['type']
|
|
108
|
+
when ITEM_TYPE
|
|
109
|
+
if operand['target'].nil? || operand['packet'].nil? || operand['raw'].nil?
|
|
110
|
+
raise TriggerInputError.new "invalid operand must contain target, packet, item, and raw: #{operand}"
|
|
111
|
+
end
|
|
112
|
+
when TRIGGER_TYPE
|
|
113
|
+
@roots << operand[operand['type']]
|
|
114
|
+
end
|
|
115
|
+
return operand
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def validate_operator(operator:)
|
|
119
|
+
unless operator.is_a?(String)
|
|
120
|
+
raise TriggerInputError.new "invalid operator: #{operator}"
|
|
121
|
+
end
|
|
122
|
+
operators = ['>', '<', '>=', '<=']
|
|
123
|
+
match_operators = ['==', '!=']
|
|
124
|
+
trigger_operators = ['AND', 'OR']
|
|
125
|
+
if @roots.empty? && operators.include?(operator)
|
|
126
|
+
return operator
|
|
127
|
+
elsif @roots.empty? && match_operators.include?(operator)
|
|
128
|
+
return operator
|
|
129
|
+
elsif @roots.size() == 2 && trigger_operators.include?(operator)
|
|
130
|
+
return operator
|
|
131
|
+
elsif operators.include?(operator)
|
|
132
|
+
raise TriggerInputError.new "invalid operator pair: '#{operator}' must be of type: #{trigger_operators}"
|
|
133
|
+
else
|
|
134
|
+
raise TriggerInputError.new "invalid operator: '#{operator}' must be of type: #{operators}"
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def validate_description(description:)
|
|
139
|
+
if description.nil?
|
|
140
|
+
left_type = @left['type']
|
|
141
|
+
right_type = @right['type']
|
|
142
|
+
return "#{@left[left_type]} #{@operator} #{@right[right_type]}"
|
|
143
|
+
end
|
|
144
|
+
unless description.is_a?(String)
|
|
145
|
+
raise TriggerInputError.new "invalid description: #{description}"
|
|
146
|
+
end
|
|
147
|
+
return description
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
attr_reader :name, :scope, :state, :group, :active, :left, :operator, :right, :dependents, :roots
|
|
151
|
+
|
|
152
|
+
#
|
|
153
|
+
def initialize(
|
|
154
|
+
name:,
|
|
155
|
+
scope:,
|
|
156
|
+
group:,
|
|
157
|
+
left:,
|
|
158
|
+
operator:,
|
|
159
|
+
right:,
|
|
160
|
+
state: false,
|
|
161
|
+
active: true,
|
|
162
|
+
description: nil,
|
|
163
|
+
dependents: nil,
|
|
164
|
+
updated_at: nil
|
|
165
|
+
)
|
|
166
|
+
if name.nil? || scope.nil? || group.nil? || left.nil? || operator.nil? || right.nil?
|
|
167
|
+
raise TriggerInputError.new "#{name}, #{scope}, #{group}, #{left}, #{operator}, or #{right} must not be nil"
|
|
168
|
+
end
|
|
169
|
+
super("#{scope}#{PRIMARY_KEY}#{group}", name: name, scope: scope)
|
|
170
|
+
@roots = []
|
|
171
|
+
@group = group
|
|
172
|
+
@state = state
|
|
173
|
+
@active = active
|
|
174
|
+
@left = validate_operand(operand: left)
|
|
175
|
+
@right = validate_operand(operand: right)
|
|
176
|
+
@operator = validate_operator(operator: operator)
|
|
177
|
+
@description = validate_description(description: description)
|
|
178
|
+
@dependents = dependents
|
|
179
|
+
@updated_at = updated_at
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def verify_triggers
|
|
183
|
+
unless @group.is_a?(String)
|
|
184
|
+
raise TriggerInputError.new "invalid group: #{@group}"
|
|
185
|
+
end
|
|
186
|
+
selected_group = OpenC3::TriggerGroupModel.get(name: @group, scope: @scope)
|
|
187
|
+
if selected_group.nil?
|
|
188
|
+
raise TriggerGroupInputError.new "failed to find group: #{@group}"
|
|
189
|
+
end
|
|
190
|
+
@dependents = [] if @dependents.nil?
|
|
191
|
+
@roots.each do | trigger |
|
|
192
|
+
model = TriggerModel.get(name: trigger, group: @group, scope: @scope)
|
|
193
|
+
if model.nil?
|
|
194
|
+
raise TriggerInputError.new "failed to find dependent trigger: #{trigger}"
|
|
195
|
+
end
|
|
196
|
+
if model.group != @group
|
|
197
|
+
raise TriggerInputError.new "failed group dependent trigger: #{trigger}"
|
|
198
|
+
end
|
|
199
|
+
unless model.dependents.include?(@name)
|
|
200
|
+
model.update_dependents(dependent: @name)
|
|
201
|
+
model.update()
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def create
|
|
207
|
+
unless Store.hget(@primary_key, @name).nil?
|
|
208
|
+
raise TriggerInputError.new "exsisting Trigger found: #{@name}"
|
|
209
|
+
end
|
|
210
|
+
verify_triggers()
|
|
211
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
212
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
213
|
+
notify(kind: 'created')
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
def update
|
|
217
|
+
verify_triggers()
|
|
218
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
219
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
220
|
+
notify(kind: 'updated')
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def enable
|
|
224
|
+
@state = true
|
|
225
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
226
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
227
|
+
notify(kind: 'enabled')
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def disable
|
|
231
|
+
@state = false
|
|
232
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
233
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
234
|
+
notify(kind: 'disabled')
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def activate
|
|
238
|
+
@active = true
|
|
239
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
240
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
241
|
+
notify(kind: 'activated')
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
def deactivate
|
|
245
|
+
@active = false
|
|
246
|
+
@state = false
|
|
247
|
+
@updated_at = Time.now.to_nsec_from_epoch
|
|
248
|
+
Store.hset(@primary_key, @name, JSON.generate(as_json(:allow_nan => true)))
|
|
249
|
+
notify(kind: 'deactivated')
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
def modify
|
|
253
|
+
raise "TODO"
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
# ["#{@scope}__DECOM__{#{@target}}__#{@packet}"]
|
|
257
|
+
def generate_topics
|
|
258
|
+
topics = Hash.new
|
|
259
|
+
if @left['type'] == ITEM_TYPE
|
|
260
|
+
topics["#{@scope}__DECOM__{#{left['target']}}__#{left['packet']}"] = 1
|
|
261
|
+
end
|
|
262
|
+
if @right['type'] == ITEM_TYPE
|
|
263
|
+
topics["#{@scope}__DECOM__{#{right['target']}}__#{right['packet']}"] = 1
|
|
264
|
+
end
|
|
265
|
+
return topics.keys
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
def update_dependents(dependent:, remove: false)
|
|
269
|
+
if remove
|
|
270
|
+
@dependents.delete(dependent)
|
|
271
|
+
elsif @dependents.index(dependent).nil?
|
|
272
|
+
@dependents << dependent
|
|
273
|
+
end
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
# @return [String] generated from the TriggerModel
|
|
277
|
+
def to_s
|
|
278
|
+
return "(TriggerModel :: #{@name} :: #{group} :: #{@description})"
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
# @return [Hash] generated from the TriggerModel
|
|
282
|
+
def as_json(*a)
|
|
283
|
+
return {
|
|
284
|
+
'name' => @name,
|
|
285
|
+
'scope' => @scope,
|
|
286
|
+
'state' => @state,
|
|
287
|
+
'active' => @active,
|
|
288
|
+
'group' => @group,
|
|
289
|
+
'description' => @description,
|
|
290
|
+
'dependents' => @dependents,
|
|
291
|
+
'left' => @left,
|
|
292
|
+
'operator' => @operator,
|
|
293
|
+
'right' => @right,
|
|
294
|
+
'updated_at' => @updated_at,
|
|
295
|
+
}
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
# @return [TriggerModel] Model generated from the passed JSON
|
|
299
|
+
def self.from_json(json, name:, scope:)
|
|
300
|
+
json = JSON.parse(json, :allow_nan => true, :create_additions => true) if String === json
|
|
301
|
+
raise "json data is nil" if json.nil?
|
|
302
|
+
|
|
303
|
+
json.transform_keys!(&:to_sym)
|
|
304
|
+
self.new(**json, name: name, scope: scope)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
# @return [] update the redis stream / trigger topic that something has changed
|
|
308
|
+
def notify(kind:)
|
|
309
|
+
notification = {
|
|
310
|
+
'kind' => kind,
|
|
311
|
+
'type' => 'trigger',
|
|
312
|
+
'data' => JSON.generate(as_json(:allow_nan => true)),
|
|
313
|
+
}
|
|
314
|
+
AutonomicTopic.write_notification(notification, scope: @scope)
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
# @param [String] kind - the status such as "event" or "error"
|
|
318
|
+
# @param [String] message - an optional message to include in the event
|
|
319
|
+
def log(kind:, message: nil)
|
|
320
|
+
notification = {
|
|
321
|
+
'kind' => kind,
|
|
322
|
+
'type' => 'log',
|
|
323
|
+
'time' => Time.now.to_i,
|
|
324
|
+
'name' => @name,
|
|
325
|
+
}
|
|
326
|
+
notification['message'] = message unless message.nil?
|
|
327
|
+
AutonomicTopic.write_notification(notification, scope: @scope)
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
end
|
|
@@ -0,0 +1,138 @@
|
|
|
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/scope_model'
|
|
23
|
+
require 'openc3/utilities/s3'
|
|
24
|
+
|
|
25
|
+
module OpenC3
|
|
26
|
+
class WidgetModel < Model
|
|
27
|
+
PRIMARY_KEY = 'openc3_widgets'
|
|
28
|
+
|
|
29
|
+
attr_accessor :name
|
|
30
|
+
attr_accessor :full_name
|
|
31
|
+
attr_accessor :filename
|
|
32
|
+
attr_accessor :s3_key
|
|
33
|
+
attr_accessor :needs_dependencies
|
|
34
|
+
|
|
35
|
+
# NOTE: The following three class methods are used by the ModelController
|
|
36
|
+
# and are reimplemented to enable various Model class methods to work
|
|
37
|
+
def self.get(name:, scope: nil)
|
|
38
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.names(scope: nil)
|
|
42
|
+
array = []
|
|
43
|
+
all(scope: scope).each do |name, _widget|
|
|
44
|
+
array << name
|
|
45
|
+
end
|
|
46
|
+
array
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.all(scope: nil)
|
|
50
|
+
tools = Store.hgetall("#{scope}__#{PRIMARY_KEY}")
|
|
51
|
+
tools.each do |key, value|
|
|
52
|
+
tools[key] = JSON.parse(value, :allow_nan => true, :create_additions => true)
|
|
53
|
+
end
|
|
54
|
+
return tools
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.all_scopes
|
|
58
|
+
result = {}
|
|
59
|
+
scopes = OpenC3::ScopeModel.all
|
|
60
|
+
scopes.each do |key, _scope|
|
|
61
|
+
widgets = all(scope: key)
|
|
62
|
+
result.merge!(widgets)
|
|
63
|
+
end
|
|
64
|
+
result
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Called by the PluginModel to allow this class to validate it's top-level keyword: "WIDGET"
|
|
68
|
+
def self.handle_config(parser, keyword, parameters, plugin: nil, needs_dependencies: false, scope:)
|
|
69
|
+
case keyword
|
|
70
|
+
when 'WIDGET'
|
|
71
|
+
parser.verify_num_parameters(1, 1, "WIDGET <Name>")
|
|
72
|
+
return self.new(name: parameters[0], plugin: plugin, needs_dependencies: needs_dependencies, scope: scope)
|
|
73
|
+
else
|
|
74
|
+
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Widget: #{keyword} #{parameters.join(" ")}")
|
|
75
|
+
end
|
|
76
|
+
return nil
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def initialize(
|
|
80
|
+
name:,
|
|
81
|
+
updated_at: nil,
|
|
82
|
+
plugin: nil,
|
|
83
|
+
needs_dependencies: false,
|
|
84
|
+
scope:
|
|
85
|
+
)
|
|
86
|
+
super("#{scope}__#{PRIMARY_KEY}", name: name, plugin: plugin, updated_at: updated_at, scope: scope)
|
|
87
|
+
@full_name = @name.capitalize + 'Widget'
|
|
88
|
+
@filename = @full_name + '.umd.min.js'
|
|
89
|
+
@s3_key = 'widgets/' + @full_name + '/' + @filename
|
|
90
|
+
@needs_dependencies = needs_dependencies
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def as_json(*a)
|
|
94
|
+
{
|
|
95
|
+
'name' => @name,
|
|
96
|
+
'updated_at' => @updated_at,
|
|
97
|
+
'plugin' => @plugin,
|
|
98
|
+
'needs_dependencies' => @needs_dependencies,
|
|
99
|
+
}
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def as_config
|
|
103
|
+
result = "WIDGET \"#{@name}\"\n"
|
|
104
|
+
result
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def handle_config(parser, keyword, parameters)
|
|
108
|
+
raise ConfigParser::Error.new(parser, "Unknown keyword and parameters for Widget: #{keyword} #{parameters.join(" ")}")
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def deploy(gem_path, variables, validate_only: false)
|
|
112
|
+
# Ensure tools bucket exists
|
|
113
|
+
OpenC3::S3Utilities.ensure_public_bucket('tools') unless validate_only
|
|
114
|
+
|
|
115
|
+
filename = gem_path + "/tools/widgets/" + @full_name + '/' + @filename
|
|
116
|
+
|
|
117
|
+
# Load widget file
|
|
118
|
+
data = File.read(filename, mode: "rb")
|
|
119
|
+
OpenC3.set_working_dir(File.dirname(filename)) do
|
|
120
|
+
data = ERB.new(data, trim_mode: "-").result(binding.set_variables(variables)) if data.is_printable?
|
|
121
|
+
end
|
|
122
|
+
unless validate_only
|
|
123
|
+
cache_control = OpenC3::S3Utilities.get_cache_control(@filename)
|
|
124
|
+
# TODO: support widgets that aren't just a single js file (and its associated map file)
|
|
125
|
+
rubys3_client = Aws::S3::Client.new
|
|
126
|
+
rubys3_client.put_object(bucket: 'tools', content_type: 'application/javascript', cache_control: cache_control, key: @s3_key, body: data)
|
|
127
|
+
data = File.read(filename + '.map', mode: "rb")
|
|
128
|
+
rubys3_client.put_object(bucket: 'tools', content_type: 'application/json', cache_control: cache_control, key: @s3_key + '.map', body: data)
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def undeploy
|
|
133
|
+
rubys3_client = Aws::S3::Client.new
|
|
134
|
+
rubys3_client.delete_object(bucket: 'tools', key: @s3_key)
|
|
135
|
+
rubys3_client.delete_object(bucket: 'tools', key: @s3_key + '.map')
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
@@ -0,0 +1,128 @@
|
|
|
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'
|
|
21
|
+
require 'openc3/models/microservice_model'
|
|
22
|
+
require 'openc3/operators/operator'
|
|
23
|
+
require 'redis'
|
|
24
|
+
require 'open3'
|
|
25
|
+
|
|
26
|
+
module OpenC3
|
|
27
|
+
# Creates new OperatorProcess objects based on querying the Redis key value store.
|
|
28
|
+
# Any keys under 'openc3_microservices' will be created into microservices.
|
|
29
|
+
class MicroserviceOperator < Operator
|
|
30
|
+
def initialize
|
|
31
|
+
Logger.microservice_name = "MicroserviceOperator"
|
|
32
|
+
super
|
|
33
|
+
|
|
34
|
+
@microservices = {}
|
|
35
|
+
@previous_microservices = {}
|
|
36
|
+
@new_microservices = {}
|
|
37
|
+
@changed_microservices = {}
|
|
38
|
+
@removed_microservices = {}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def convert_microservice_to_process_definition(microservice_name, microservice_config)
|
|
42
|
+
process_definition = ["ruby", "plugin_microservice.rb"]
|
|
43
|
+
work_dir = "/openc3/lib/openc3/microservices"
|
|
44
|
+
env = microservice_config["env"].dup
|
|
45
|
+
if microservice_config["needs_dependencies"]
|
|
46
|
+
env['GEM_HOME'] = '/gems'
|
|
47
|
+
else
|
|
48
|
+
env['GEM_HOME'] = nil
|
|
49
|
+
end
|
|
50
|
+
env['OPENC3_MICROSERVICE_NAME'] = microservice_name
|
|
51
|
+
container = microservice_config["container"]
|
|
52
|
+
scope = microservice_name.split("__")[0]
|
|
53
|
+
return process_definition, work_dir, env, scope, container
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def update
|
|
57
|
+
@previous_microservices = @microservices.dup
|
|
58
|
+
# Get all the microservice configuration
|
|
59
|
+
@microservices = MicroserviceModel.all
|
|
60
|
+
|
|
61
|
+
# Detect new and changed microservices
|
|
62
|
+
@new_microservices = {}
|
|
63
|
+
@changed_microservices = {}
|
|
64
|
+
@microservices.each do |microservice_name, microservice_config|
|
|
65
|
+
if @previous_microservices[microservice_name]
|
|
66
|
+
if @previous_microservices[microservice_name] != microservice_config
|
|
67
|
+
scope = microservice_name.split("__")[0]
|
|
68
|
+
Logger.info("Changed microservice detected: #{microservice_name}\nWas: #{@previous_microservices[microservice_name]}\nIs: #{microservice_config}", scope: scope)
|
|
69
|
+
@changed_microservices[microservice_name] = microservice_config
|
|
70
|
+
end
|
|
71
|
+
else
|
|
72
|
+
scope = microservice_name.split("__")[0]
|
|
73
|
+
Logger.info("New microservice detected: #{microservice_name}", scope: scope)
|
|
74
|
+
@new_microservices[microservice_name] = microservice_config
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Detect removed microservices
|
|
79
|
+
@removed_microservices = {}
|
|
80
|
+
@previous_microservices.each do |microservice_name, microservice_config|
|
|
81
|
+
unless @microservices[microservice_name]
|
|
82
|
+
scope = microservice_name.split("__")[0]
|
|
83
|
+
Logger.info("Removed microservice detected: #{microservice_name}", scope: scope)
|
|
84
|
+
@removed_microservices[microservice_name] = microservice_config
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# Convert to processes
|
|
89
|
+
@mutex.synchronize do
|
|
90
|
+
@new_microservices.each do |microservice_name, microservice_config|
|
|
91
|
+
cmd_array, work_dir, env, scope, container = convert_microservice_to_process_definition(microservice_name, microservice_config)
|
|
92
|
+
if cmd_array
|
|
93
|
+
process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container)
|
|
94
|
+
@new_processes[microservice_name] = process
|
|
95
|
+
@processes[microservice_name] = process
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@changed_microservices.each do |microservice_name, microservice_config|
|
|
100
|
+
cmd_array, work_dir, env, scope, container = convert_microservice_to_process_definition(microservice_name, microservice_config)
|
|
101
|
+
if cmd_array
|
|
102
|
+
process = @processes[microservice_name]
|
|
103
|
+
if process
|
|
104
|
+
process.process_definition = cmd_array
|
|
105
|
+
process.work_dir = work_dir
|
|
106
|
+
process.new_temp_dir = nil
|
|
107
|
+
process.env = env
|
|
108
|
+
@changed_processes[microservice_name] = process
|
|
109
|
+
else # TODO: How is this even possible?
|
|
110
|
+
Logger.error("Changed microservice #{microservice_name} does not exist. Creating new...", scope: scope)
|
|
111
|
+
process = OperatorProcess.new(cmd_array, work_dir: work_dir, env: env, scope: scope, container: container)
|
|
112
|
+
@new_processes[microservice_name] = process
|
|
113
|
+
@processes[microservice_name] = process
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
@removed_microservices.each do |microservice_name, microservice_config|
|
|
119
|
+
process = @processes[microservice_name]
|
|
120
|
+
@processes.delete(microservice_name)
|
|
121
|
+
@removed_processes[microservice_name] = process
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
OpenC3::MicroserviceOperator.run if __FILE__ == $0
|