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,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
|