cosmos 5.0.2 → 5.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/bin/cosmos +183 -42
  3. data/data/config/microservice.yaml +47 -35
  4. data/data/config/plugins.yaml +10 -147
  5. data/data/config/target.yaml +70 -0
  6. data/data/config/tool.yaml +37 -31
  7. data/ext/cosmos/ext/cosmos_io/cosmos_io.c +14 -14
  8. data/ext/cosmos/ext/packet/packet.c +3 -3
  9. data/ext/cosmos/ext/structure/structure.c +31 -31
  10. data/lib/cosmos/api/api.rb +1 -25
  11. data/lib/cosmos/api/cmd_api.rb +17 -6
  12. data/lib/cosmos/api/config_api.rb +10 -4
  13. data/lib/cosmos/api/limits_api.rb +1 -1
  14. data/lib/cosmos/api/settings_api.rb +19 -7
  15. data/lib/cosmos/api/target_api.rb +2 -2
  16. data/lib/cosmos/api/tlm_api.rb +65 -41
  17. data/lib/cosmos/config/config_parser.rb +19 -22
  18. data/lib/cosmos/config/meta_config_parser.rb +1 -1
  19. data/lib/cosmos/conversions/generic_conversion.rb +2 -2
  20. data/lib/cosmos/conversions/polynomial_conversion.rb +5 -8
  21. data/lib/cosmos/conversions/segmented_polynomial_conversion.rb +26 -9
  22. data/lib/cosmos/io/json_drb.rb +5 -1
  23. data/lib/cosmos/logs/log_writer.rb +78 -29
  24. data/lib/cosmos/microservices/cleanup_microservice.rb +28 -29
  25. data/lib/cosmos/microservices/decom_microservice.rb +1 -1
  26. data/lib/cosmos/microservices/interface_microservice.rb +0 -16
  27. data/lib/cosmos/microservices/microservice.rb +3 -3
  28. data/lib/cosmos/microservices/reducer_microservice.rb +12 -10
  29. data/lib/cosmos/models/cvt_model.rb +6 -6
  30. data/lib/cosmos/models/gem_model.rb +9 -3
  31. data/lib/cosmos/models/info_model.rb +1 -1
  32. data/lib/cosmos/models/interface_model.rb +16 -7
  33. data/lib/cosmos/models/interface_status_model.rb +1 -1
  34. data/lib/cosmos/models/metadata_model.rb +69 -219
  35. data/lib/cosmos/models/metric_model.rb +2 -2
  36. data/lib/cosmos/models/microservice_model.rb +7 -4
  37. data/lib/cosmos/models/microservice_status_model.rb +1 -1
  38. data/lib/cosmos/models/model.rb +23 -16
  39. data/lib/cosmos/models/note_model.rb +122 -0
  40. data/lib/cosmos/models/ping_model.rb +2 -1
  41. data/lib/cosmos/models/plugin_model.rb +108 -48
  42. data/lib/cosmos/models/process_status_model.rb +1 -1
  43. data/lib/cosmos/models/scope_model.rb +10 -25
  44. data/lib/cosmos/models/settings_model.rb +55 -0
  45. data/lib/cosmos/models/sorted_model.rb +167 -0
  46. data/lib/cosmos/models/target_model.rb +143 -27
  47. data/lib/cosmos/models/tool_config_model.rb +38 -0
  48. data/lib/cosmos/models/tool_model.rb +9 -9
  49. data/lib/cosmos/models/widget_model.rb +11 -11
  50. data/lib/cosmos/operators/microservice_operator.rb +2 -1
  51. data/lib/cosmos/packets/packet.rb +24 -1
  52. data/lib/cosmos/packets/packet_config.rb +2 -2
  53. data/lib/cosmos/packets/packet_item.rb +57 -0
  54. data/lib/cosmos/packets/packet_item_limits.rb +14 -2
  55. data/lib/cosmos/packets/parsers/packet_item_parser.rb +1 -1
  56. data/lib/cosmos/packets/parsers/packet_parser.rb +1 -1
  57. data/lib/cosmos/packets/parsers/xtce_parser.rb +1 -1
  58. data/lib/cosmos/packets/structure.rb +30 -33
  59. data/lib/cosmos/packets/structure_item.rb +10 -1
  60. data/lib/cosmos/script/api_shared.rb +30 -25
  61. data/lib/cosmos/script/calendar.rb +37 -15
  62. data/lib/cosmos/script/commands.rb +5 -7
  63. data/lib/cosmos/script/script.rb +19 -39
  64. data/lib/cosmos/script/storage.rb +92 -105
  65. data/lib/cosmos/system/system.rb +2 -1
  66. data/lib/cosmos/tools/table_manager/table_config.rb +16 -1
  67. data/lib/cosmos/tools/table_manager/table_item.rb +1 -1
  68. data/lib/cosmos/tools/table_manager/table_manager_core.rb +213 -309
  69. data/lib/cosmos/top_level.rb +5 -1
  70. data/lib/cosmos/topics/autonomic_topic.rb +2 -2
  71. data/lib/cosmos/topics/calendar_topic.rb +1 -1
  72. data/lib/cosmos/topics/command_decom_topic.rb +35 -1
  73. data/lib/cosmos/topics/command_topic.rb +6 -4
  74. data/lib/cosmos/topics/config_topic.rb +68 -0
  75. data/lib/cosmos/topics/interface_topic.rb +8 -8
  76. data/lib/cosmos/topics/limits_event_topic.rb +5 -3
  77. data/lib/cosmos/topics/notifications_topic.rb +1 -1
  78. data/lib/cosmos/topics/router_topic.rb +9 -9
  79. data/lib/cosmos/topics/telemetry_decom_topic.rb +5 -1
  80. data/lib/cosmos/topics/telemetry_topic.rb +1 -1
  81. data/lib/cosmos/topics/timeline_topic.rb +1 -1
  82. data/lib/cosmos/topics/topic.rb +23 -8
  83. data/lib/cosmos/utilities/logger.rb +4 -3
  84. data/lib/cosmos/utilities/metric.rb +32 -26
  85. data/lib/cosmos/utilities/s3.rb +61 -0
  86. data/lib/cosmos/utilities/s3_file_cache.rb +12 -6
  87. data/lib/cosmos/utilities/store.rb +1 -0
  88. data/lib/cosmos/utilities/store_autoload.rb +25 -134
  89. data/lib/cosmos/version.rb +5 -4
  90. data/templates/plugin-template/plugin.gemspec +0 -2
  91. metadata +12 -10
  92. data/bin/xtce_converter +0 -92
  93. data/lib/cosmos/models/narrative_model.rb +0 -280
@@ -1,280 +0,0 @@
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
- # This program may also be used under the terms of a commercial or
17
- # enterprise edition license of COSMOS if purchased from the
18
- # copyright holder
19
-
20
- # https://www.rubydoc.info/gems/redis/Redis/Commands/SortedSets
21
-
22
- require 'cosmos/topics/calendar_topic'
23
-
24
- module Cosmos
25
-
26
- class NarrativeError < StandardError; end
27
-
28
- class NarrativeInputError < NarrativeError; end
29
-
30
- class NarrativeOverlapError < NarrativeError; end
31
-
32
- class NarrativeModel < Model
33
-
34
- CHRONICLE_TYPE = 'narrative'.freeze
35
- PRIMARY_KEY = '__NARRATIVE'.freeze
36
-
37
- def self.pk(scope)
38
- return "#{scope}#{PRIMARY_KEY}"
39
- end
40
-
41
- # @return [Array|nil] Array up to 100 of this model or empty array
42
- def self.get(start:, stop:, scope:, limit: 100)
43
- if start > stop
44
- raise MetadataInputError.new "start: #{start} must be before stop: #{stop}"
45
- end
46
- pk = self.pk(scope)
47
- array = Store.zrangebyscore(pk, start, stop, :limit => [0, limit])
48
- ret_array = Array.new
49
- array.each do |value|
50
- ret_array << JSON.parse(value)
51
- end
52
- return ret_array
53
- end
54
-
55
- # @return [Array<Hash>] Array up to the limit of the models (as Hash objects) stored under the primary key
56
- def self.all(scope:, limit: 100)
57
- pk = self.pk(scope)
58
- array = Store.zrange(pk, 0, -1, :limit => [0, limit])
59
- ret_array = Array.new
60
- array.each do |value|
61
- ret_array << JSON.parse(value)
62
- end
63
- return ret_array
64
- end
65
-
66
- # @return [Integer] count of the members stored under the primary key
67
- def self.count(scope:)
68
- return Store.zcard(self.pk(scope))
69
- end
70
-
71
- # @return [String|nil] String of the saved json or nil if score not found under primary_key
72
- def self.score(score:, scope:)
73
- pk = self.pk(scope)
74
- array = Store.zrangebyscore(pk, score, score, :limit => [0, 1])
75
- array.each do |value|
76
- return JSON.parse(value)
77
- end
78
- return nil
79
- end
80
-
81
- # Remove member from a sorted set based on the score.
82
- # @return [Integer] count of the members removed
83
- def self.destroy(scope:, score:)
84
- pk = self.pk(scope)
85
- Store.zremrangebyscore(pk, score, score)
86
- end
87
-
88
- # Remove members from min to max of the sorted set.
89
- # @return [Integer] count of the members removed
90
- def self.range_destroy(scope:, min:, max:)
91
- pk = self.pk(scope)
92
- Store.zremrangebyscore(pk, min, max)
93
- end
94
-
95
- # @return [NarrativeModel] Model generated from the passed JSON
96
- def self.from_json(json, scope:)
97
- json = JSON.parse(json) if String === json
98
- raise "json data is nil" if json.nil?
99
-
100
- json.transform_keys!(&:to_sym)
101
- self.new(**json, scope: scope)
102
- end
103
-
104
- attr_reader :start, :stop, :duration, :color, :description, :type
105
-
106
- # @param [String] scope - Cosmos scope to track event to
107
- # @param [Integer] start - start of the event in seconds from Epoch
108
- # @param [Integer] stop - stop of the event in seconds from Epoch
109
- # @param [String] color - The event color
110
- # @param [String] description - What the event is about
111
- def initialize(
112
- scope:,
113
- start:,
114
- stop:,
115
- color:,
116
- description:,
117
- type: CHRONICLE_TYPE,
118
- updated_at: 0,
119
- duration: 0
120
- )
121
- super(NarrativeModel.pk(scope), name: start.to_s, scope: scope)
122
- set_input(
123
- start: start,
124
- stop: stop,
125
- color: color,
126
- description: description,
127
- )
128
- @type = type
129
- @updated_at = updated_at
130
- end
131
-
132
- # validate color
133
- def validate_color(color)
134
- if color.nil?
135
- color = '#%06x' % (rand * 0xffffff)
136
- end
137
- valid_color = color =~ /(#*)([0-9,a-f,A-f]{6})/
138
- if valid_color.nil?
139
- raise MetadataInputError.new "invalid color but in hex format. #FF0000"
140
- end
141
-
142
- color = "##{color}" unless color.start_with?('#')
143
- return color
144
- end
145
-
146
- # validate the input to the rules we have created for timelines.
147
- # - An entry's start MUST be before the stop.
148
- # - An entry's description MUST a String.
149
- def validate_input(start:, stop:, color:, description:)
150
- begin
151
- DateTime.strptime(start.to_s, '%s')
152
- DateTime.strptime(stop.to_s, '%s')
153
- rescue Date::Error
154
- raise NarrativeInputError.new "failed validation input must be seconds: #{start}, #{stop}"
155
- end
156
- validate_color(color)
157
- duration = stop - start
158
- if duration <= 0
159
- raise NarrativeInputError.new "start: #{start} must be before stop: #{stop}"
160
- elsif description.is_a?(String) == false
161
- raise NarrativeInputError.new "description must be a String: #{description}"
162
- end
163
- end
164
-
165
- # Set the values of the instance, @start, @stop, @description...
166
- def set_input(start:, stop:, color:, description:)
167
- begin
168
- DateTime.strptime(start.to_s, '%s')
169
- DateTime.strptime(stop.to_s, '%s')
170
- rescue ArgumentError
171
- raise NarrativeInputError.new "invalid input must be seconds: #{start}, #{stop}"
172
- end
173
- @start = start
174
- @stop = stop
175
- @duration = @stop - @start
176
- @color = color
177
- @description = description
178
- end
179
-
180
- # validate_time will be called on create and update this will validate
181
- # that no other chronicle event or metadata had been saved for that time.
182
- # One event or metadata per second to ensure data can be updated.
183
- #
184
- # @param [Integer] ignore_score - should be nil unless you want to ignore
185
- # a time when doing an update
186
- def validate_time(ignore_score: nil)
187
- array = Store.zrangebyscore(@primary_key, @start, @start, :limit => [0, 1])
188
- array.each do |value|
189
- entry = JSON.parse(value)
190
- if ignore_score == entry['start']
191
- next
192
- else
193
- return entry
194
- end
195
- end
196
- return nil
197
- end
198
-
199
- # Update the Redis hash at primary_key and set the score equal to the start Epoch time
200
- # the member is set to the JSON generated via calling as_json
201
- def create
202
- validate_input(start: @start, stop: @stop, color: @color, description: @description)
203
- collision = validate_time()
204
- unless collision.nil?
205
- raise NarrativeOverlapError.new "no chronicles can overlap, collision: #{collision}"
206
- end
207
-
208
- @updated_at = Time.now.to_nsec_from_epoch
209
- Store.zadd(@primary_key, @start, JSON.generate(as_json()))
210
- notify(kind: 'created')
211
- end
212
-
213
- # Update the Redis hash at primary_key and remove the current activity at the current score
214
- # and update the score to the new score equal to the start Epoch time this uses a multi
215
- # to execute both the remove and create. The member via the JSON generated via calling as_json
216
- def update(start:, stop:, color:, description:)
217
- validate_input(start: start, stop: stop, color: color, description: description)
218
- old_start = @start
219
-
220
- set_input(
221
- start: start,
222
- stop: stop,
223
- color: color,
224
- description: description,
225
- )
226
- @updated_at = Time.now.to_nsec_from_epoch
227
-
228
- collision = validate_time(ignore_score: old_start)
229
- unless collision.nil?
230
- raise NarrativeOverlapError.new "failed to update #{old_start}, no chronicles can overlap, collision: #{collision}"
231
- end
232
-
233
- Store.multi do |multi|
234
- multi.zremrangebyscore(@primary_key, old_start, old_start)
235
- multi.zadd(@primary_key, @start, JSON.generate(as_json()))
236
- end
237
- notify(kind: 'updated', extra: old_start)
238
- return @start
239
- end
240
-
241
- # destroy the activity from the redis database
242
- def destroy
243
- Store.zremrangebyscore(@primary_key, @start, @start)
244
- notify(kind: 'deleted')
245
- end
246
-
247
- # @return [] update the redis stream / timeline topic that something has changed
248
- def notify(kind:, extra: nil)
249
- notification = {
250
- 'data' => JSON.generate(as_json()),
251
- 'kind' => kind,
252
- 'type' => 'calendar',
253
- }
254
- notification['extra'] = extra unless extra.nil?
255
- begin
256
- CalendarTopic.write_entry(notification, scope: @scope)
257
- rescue StandardError => e
258
- raise NarrativeError.new "Failed to write to stream: #{notification}, #{e}"
259
- end
260
- end
261
-
262
- # @return [Hash] generated from the NarrativeModel
263
- def as_json
264
- return {
265
- 'color' => @color,
266
- 'start' => @start,
267
- 'stop' => @stop,
268
- 'description' => @description,
269
- 'type' => CHRONICLE_TYPE,
270
- 'scope' => @scope,
271
- 'updated_at' => @updated_at,
272
- }
273
- end
274
-
275
- # @return [String] string view of NarrativeModel
276
- def to_s
277
- return "<NarrativeModel ->: #{@start}, x: #{@stop}, c: #{@color}, d: #{@description}>"
278
- end
279
- end
280
- end