inventory_refresh 0.2.3 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +0 -1
  3. data/.travis.yml +6 -8
  4. data/inventory_refresh.gemspec +3 -5
  5. data/lib/inventory_refresh/application_record_iterator.rb +9 -26
  6. data/lib/inventory_refresh/exception.rb +8 -0
  7. data/lib/inventory_refresh/inventory_collection/builder.rb +6 -6
  8. data/lib/inventory_refresh/inventory_collection/data_storage.rb +0 -9
  9. data/lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb +35 -144
  10. data/lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb +1 -44
  11. data/lib/inventory_refresh/inventory_collection/index/proxy.rb +6 -34
  12. data/lib/inventory_refresh/inventory_collection/index/type/base.rb +0 -8
  13. data/lib/inventory_refresh/inventory_collection/references_storage.rb +0 -17
  14. data/lib/inventory_refresh/inventory_collection/scanner.rb +1 -87
  15. data/lib/inventory_refresh/inventory_collection/serialization.rb +10 -16
  16. data/lib/inventory_refresh/inventory_collection.rb +36 -110
  17. data/lib/inventory_refresh/inventory_object.rb +34 -68
  18. data/lib/inventory_refresh/inventory_object_lazy.rb +10 -17
  19. data/lib/inventory_refresh/persister.rb +63 -29
  20. data/lib/inventory_refresh/save_collection/base.rb +2 -4
  21. data/lib/inventory_refresh/save_collection/saver/base.rb +8 -108
  22. data/lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb +48 -126
  23. data/lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb +19 -1
  24. data/lib/inventory_refresh/save_collection/saver/retention_helper.rb +3 -68
  25. data/lib/inventory_refresh/save_collection/saver/sql_helper.rb +0 -125
  26. data/lib/inventory_refresh/save_collection/saver/sql_helper_update.rb +5 -9
  27. data/lib/inventory_refresh/save_collection/saver/sql_helper_upsert.rb +9 -17
  28. data/lib/inventory_refresh/save_collection/sweeper.rb +91 -18
  29. data/lib/inventory_refresh/save_collection/topological_sort.rb +5 -5
  30. data/lib/inventory_refresh/save_inventory.rb +12 -5
  31. data/lib/inventory_refresh/version.rb +1 -1
  32. data/lib/inventory_refresh.rb +0 -2
  33. metadata +15 -57
  34. data/lib/inventory_refresh/save_collection/saver/batch.rb +0 -17
  35. data/lib/inventory_refresh/save_collection/saver/default.rb +0 -57
  36. data/lib/inventory_refresh/target.rb +0 -73
  37. data/lib/inventory_refresh/target_collection.rb +0 -92
metadata CHANGED
@@ -1,55 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inventory_refresh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.3
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-15 00:00:00.000000000 Z
11
+ date: 2019-05-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '5.0'
20
- - - "<"
21
- - !ruby/object:Gem::Version
22
- version: '6.1'
23
20
  type: :runtime
24
21
  prerelease: false
25
22
  version_requirements: !ruby/object:Gem::Requirement
26
23
  requirements:
27
- - - ">="
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '5.0'
30
- - - "<"
31
- - !ruby/object:Gem::Version
32
- version: '6.1'
33
27
  - !ruby/object:Gem::Dependency
34
28
  name: more_core_extensions
35
29
  requirement: !ruby/object:Gem::Requirement
36
30
  requirements:
37
- - - ">="
31
+ - - "~>"
38
32
  - !ruby/object:Gem::Version
39
33
  version: '3.5'
40
- - - "<"
41
- - !ruby/object:Gem::Version
42
- version: '5'
43
34
  type: :runtime
44
35
  prerelease: false
45
36
  version_requirements: !ruby/object:Gem::Requirement
46
37
  requirements:
47
- - - ">="
38
+ - - "~>"
48
39
  - !ruby/object:Gem::Version
49
40
  version: '3.5'
50
- - - "<"
51
- - !ruby/object:Gem::Version
52
- version: '5'
53
41
  - !ruby/object:Gem::Dependency
54
42
  name: pg
55
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,14 +72,14 @@ dependencies:
84
72
  requirements:
85
73
  - - "~>"
86
74
  - !ruby/object:Gem::Version
87
- version: '2.0'
75
+ version: 2.0.1
88
76
  type: :development
89
77
  prerelease: false
90
78
  version_requirements: !ruby/object:Gem::Requirement
91
79
  requirements:
92
80
  - - "~>"
93
81
  - !ruby/object:Gem::Version
94
- version: '2.0'
82
+ version: 2.0.1
95
83
  - !ruby/object:Gem::Dependency
96
84
  name: factory_bot
97
85
  requirement: !ruby/object:Gem::Requirement
@@ -134,34 +122,6 @@ dependencies:
134
122
  - - "~>"
135
123
  - !ruby/object:Gem::Version
136
124
  version: '3.0'
137
- - !ruby/object:Gem::Dependency
138
- name: rubocop
139
- requirement: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- version: '0'
144
- type: :development
145
- prerelease: false
146
- version_requirements: !ruby/object:Gem::Requirement
147
- requirements:
148
- - - ">="
149
- - !ruby/object:Gem::Version
150
- version: '0'
151
- - !ruby/object:Gem::Dependency
152
- name: rubocop-performance
153
- requirement: !ruby/object:Gem::Requirement
154
- requirements:
155
- - - ">="
156
- - !ruby/object:Gem::Version
157
- version: '0'
158
- type: :development
159
- prerelease: false
160
- version_requirements: !ruby/object:Gem::Requirement
161
- requirements:
162
- - - ">="
163
- - !ruby/object:Gem::Version
164
- version: '0'
165
125
  - !ruby/object:Gem::Dependency
166
126
  name: simplecov
167
127
  requirement: !ruby/object:Gem::Requirement
@@ -177,7 +137,7 @@ dependencies:
177
137
  - !ruby/object:Gem::Version
178
138
  version: '0'
179
139
  description: Topological Inventory Persister
180
- email:
140
+ email:
181
141
  executables: []
182
142
  extensions: []
183
143
  extra_rdoc_files: []
@@ -204,6 +164,7 @@ files:
204
164
  - lib/inventory_refresh.rb
205
165
  - lib/inventory_refresh/application_record_iterator.rb
206
166
  - lib/inventory_refresh/application_record_reference.rb
167
+ - lib/inventory_refresh/exception.rb
207
168
  - lib/inventory_refresh/graph.rb
208
169
  - lib/inventory_refresh/graph/topological_sort.rb
209
170
  - lib/inventory_refresh/inventory_collection.rb
@@ -231,9 +192,7 @@ files:
231
192
  - lib/inventory_refresh/persister.rb
232
193
  - lib/inventory_refresh/save_collection/base.rb
233
194
  - lib/inventory_refresh/save_collection/saver/base.rb
234
- - lib/inventory_refresh/save_collection/saver/batch.rb
235
195
  - lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb
236
- - lib/inventory_refresh/save_collection/saver/default.rb
237
196
  - lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb
238
197
  - lib/inventory_refresh/save_collection/saver/retention_helper.rb
239
198
  - lib/inventory_refresh/save_collection/saver/sql_helper.rb
@@ -242,14 +201,12 @@ files:
242
201
  - lib/inventory_refresh/save_collection/sweeper.rb
243
202
  - lib/inventory_refresh/save_collection/topological_sort.rb
244
203
  - lib/inventory_refresh/save_inventory.rb
245
- - lib/inventory_refresh/target.rb
246
- - lib/inventory_refresh/target_collection.rb
247
204
  - lib/inventory_refresh/version.rb
248
205
  homepage: https://github.com/ManageIQ/inventory_refresh
249
206
  licenses:
250
207
  - Apache-2.0
251
208
  metadata: {}
252
- post_install_message:
209
+ post_install_message:
253
210
  rdoc_options: []
254
211
  require_paths:
255
212
  - lib
@@ -264,8 +221,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
221
  - !ruby/object:Gem::Version
265
222
  version: '0'
266
223
  requirements: []
267
- rubygems_version: 3.2.0.rc.2
268
- signing_key:
224
+ rubyforge_project:
225
+ rubygems_version: 2.7.6.2
226
+ signing_key:
269
227
  specification_version: 4
270
228
  summary: Topological Inventory Persister
271
229
  test_files: []
@@ -1,17 +0,0 @@
1
- require "inventory_refresh/save_collection/saver/concurrent_safe_batch"
2
-
3
- module InventoryRefresh::SaveCollection
4
- module Saver
5
- class Batch < InventoryRefresh::SaveCollection::Saver::ConcurrentSafeBatch
6
- private
7
-
8
- # Just returning manager ref transformed to column names, for strategies that do not expect to have unique DB
9
- # indexes.
10
- #
11
- # @return [Array<Symbol>] manager ref transformed to column names
12
- def unique_index_columns
13
- inventory_collection.manager_ref_to_cols.map(&:to_sym)
14
- end
15
- end
16
- end
17
- end
@@ -1,57 +0,0 @@
1
- require "inventory_refresh/save_collection/saver/base"
2
-
3
- module InventoryRefresh::SaveCollection
4
- module Saver
5
- class Default < InventoryRefresh::SaveCollection::Saver::Base
6
- private
7
-
8
- # Updates the passed record with hash data and stores primary key value into inventory_object.
9
- #
10
- # @param record [ApplicationRecord] record we want to update in DB
11
- # @param hash [Hash] data we want to update the record with
12
- # @param inventory_object [InventoryRefresh::InventoryObject] InventoryObject instance where we will store primary
13
- # key value
14
- def update_record!(record, hash, inventory_object)
15
- record.assign_attributes(hash.except(:id))
16
- if !inventory_collection.check_changed? || record.changed?
17
- record.save
18
- inventory_collection.store_updated_records(record)
19
- end
20
-
21
- inventory_object.id = record.id
22
- end
23
-
24
- # Creates a new record in the DB using the passed hash data
25
- #
26
- # @param hash [Hash] hash with data we want to persist to DB
27
- # @param inventory_object [InventoryRefresh::InventoryObject] InventoryObject instance where we will store primary
28
- # key value
29
- def create_record!(hash, inventory_object)
30
- record = inventory_collection.model_class.create!(hash.except(:id))
31
- inventory_collection.store_created_records(record)
32
-
33
- inventory_object.id = record.id
34
- end
35
-
36
- # Asserts we do not have duplicate records in the DB. If the record is duplicate we will destroy it.
37
- #
38
- # @param record [ApplicationRecord] record we want to update in DB
39
- # @param index [String] manager_uuid of the record
40
- # @return [Boolean] false if the record is duplicate
41
- def assert_unique_record(record, index)
42
- # TODO(lsmola) can go away once we indexed our DB with unique indexes
43
- if unique_db_indexes.include?(index) # Include on Set is O(1)
44
- # We have a duplicate in the DB, destroy it. A find_each method does automatically .order(:id => :asc)
45
- # so we always keep the oldest record in the case of duplicates.
46
- logger.warn("A duplicate record was detected and destroyed, inventory_collection: "\
47
- "'#{inventory_collection}', record: '#{record}', duplicate_index: '#{index}'")
48
- record.destroy
49
- return false
50
- else
51
- unique_db_indexes << index
52
- end
53
- true
54
- end
55
- end
56
- end
57
- end
@@ -1,73 +0,0 @@
1
- module InventoryRefresh
2
- class Target
3
- attr_reader :association, :manager_ref, :event_id, :options
4
-
5
- # @param association [Symbol] An existing association on Manager, that lists objects represented by a Target, naming
6
- # should be the same of association of a counterpart InventoryCollection object
7
- # @param manager_ref [Hash] A Hash that can be used to find_by on a given association and returning a unique object.
8
- # The keys should be the same as the keys of the counterpart InventoryObject
9
- # @param manager [ManageIQ::Providers::BaseManager] The Manager owning the Target
10
- # @param manager_id [Integer] A primary key of the Manager owning the Target
11
- # @param event_id [Integer] A primary key of the EmsEvent associated with the Target
12
- # @param options [Hash] A free form options hash
13
- def initialize(association:, manager_ref:, manager: nil, manager_id: nil, event_id: nil, options: {})
14
- raise "Provide either :manager or :manager_id argument" if manager.nil? && manager_id.nil?
15
-
16
- @manager = manager
17
- @manager_id = manager_id
18
- @association = association
19
- @manager_ref = manager_ref
20
- @event_id = event_id
21
- @options = options
22
- end
23
-
24
- # A Rails recommended interface for deserializing an object
25
- # @return [InventoryRefresh::Target] InventoryRefresh::Target instance
26
- def self.load(*args)
27
- new(*args)
28
- end
29
-
30
- # A Rails recommended interface for serializing an object
31
- #
32
- # @param obj [InventoryRefresh::Target] InventoryRefresh::Target instance we want to serialize
33
- # @return [Hash] serialized object
34
- def self.dump(obj)
35
- obj.dump
36
- end
37
-
38
- # Returns a serialized InventoryRefresh::Target object. This can be used to initialize a new object, then the object
39
- # target acts the same as the object InventoryRefresh::Target.new(target.serialize)
40
- #
41
- # @return [Hash] serialized object
42
- def dump
43
- {
44
- :manager_id => manager_id,
45
- :association => association,
46
- :manager_ref => manager_ref,
47
- :event_id => event_id,
48
- :options => options
49
- }
50
- end
51
-
52
- alias id dump
53
- alias name manager_ref
54
-
55
- # @return [ManageIQ::Providers::BaseManager] The Manager owning the Target
56
- def manager
57
- @manager || ManageIQ::Providers::BaseManager.find(@manager_id)
58
- end
59
-
60
- # @return [Integer] A primary key of the Manager owning the Target
61
- def manager_id
62
- @manager_id || manager.try(:id)
63
- end
64
-
65
- # Loads InventoryRefresh::Target ApplicationRecord representation from our DB, this requires that InventoryRefresh::Target
66
- # has been refreshed, otherwise the AR object can be missing.
67
- #
68
- # @return [ApplicationRecord] A InventoryRefresh::Target loaded from the database as AR object
69
- def load_from_db
70
- manager.public_send(association).find_by(manager_ref)
71
- end
72
- end
73
- end
@@ -1,92 +0,0 @@
1
- require "active_support/core_ext/module/delegation"
2
-
3
- module InventoryRefresh
4
- class TargetCollection
5
- attr_reader :targets
6
-
7
- delegate :<<, :to => :targets
8
-
9
- # @param manager [ManageIQ::Providers::BaseManager] manager owning the TargetCollection
10
- # @param manager_id [Integer] primary key of manager owning the TargetCollection
11
- # @param event [EmsEvent] EmsEvent associated with the TargetCollection
12
- # @param targets [Array<InventoryRefresh::Target, ApplicationRecord>] Array of InventoryRefresh::Target objects or
13
- # ApplicationRecord objects
14
- def initialize(manager: nil, manager_id: nil, event: nil, targets: [])
15
- @manager = manager
16
- @manager_id = manager_id
17
- @event = event
18
- @targets = targets
19
- end
20
-
21
- # @param association [Symbol] An existing association on Manager, that lists objects represented by a Target, naming
22
- # should be the same of association of a counterpart InventoryCollection object
23
- # @param manager_ref [Hash] A Hash that can be used to find_by on a given association and returning a unique object.
24
- # The keys should be the same as the keys of the counterpart InventoryObject
25
- # @param manager [ManageIQ::Providers::BaseManager] The Manager owning the Target
26
- # @param manager_id [Integer] A primary key of the Manager owning the Target
27
- # @param event_id [Integer] A primary key of the EmsEvent associated with the Target
28
- # @param options [Hash] A free form options hash
29
- def add_target(association:, manager_ref:, manager: nil, manager_id: nil, event_id: nil, options: {})
30
- self << InventoryRefresh::Target.new(:association => association,
31
- :manager_ref => manager_ref,
32
- :manager => manager || @manager,
33
- :manager_id => manager_id || @manager_id || @manager.try(:id),
34
- :event_id => event_id || @event.try(:id),
35
- :options => options)
36
- end
37
-
38
- # @return [String] A String containing a summary
39
- def name
40
- "Collection of #{targets.size} targets"
41
- end
42
-
43
- # @return [String] A String containing an id of each target in the TargetCollection
44
- def id
45
- "Collection of targets with id: #{targets.collect(&:name)}"
46
- end
47
-
48
- # Returns targets in a format:
49
- # {
50
- # :vms => {:ems_ref => Set.new(["vm_ref_1", "vm_ref2"])},
51
- # :network_ports => {:ems_ref => Set.new(["network_port_1", "network_port2"])
52
- # }
53
- #
54
- # Then we can quickly access all objects affected by:
55
- # NetworkPort.where(target_collection.manager_refs_by_association[:network_ports].to_a) =>
56
- # return AR objects with ems_refs ["network_port_1", "network_port2"]
57
- # And we can get a list of ids for the API query by:
58
- # target_collection.manager_refs_by_association[:network_ports][:ems_ref].to_a =>
59
- # ["network_port_1", "network_port2"]
60
- #
61
- # Only targets of a type InventoryRefresh::Target are processed, any other targets present should be converted to
62
- # InventoryRefresh::Target, e.g. in the Inventory::Collector code.
63
- def manager_refs_by_association
64
- @manager_refs_by_association ||= targets.select { |x| x.kind_of?(InventoryRefresh::Target) }.each_with_object({}) do |x, obj|
65
- if obj[x.association].blank?
66
- obj[x.association] = x.manager_ref.each_with_object({}) { |(key, value), hash| hash[key] = Set.new([value]) }
67
- else
68
- obj[x.association].each do |key, value|
69
- value << x.manager_ref[key]
70
- end
71
- end
72
- end
73
- end
74
-
75
- # Resets the cached @manager_refs_by_association to enforce reload when calling :manager_refs_by_association method
76
- def manager_refs_by_association_reset
77
- @manager_refs_by_association = nil
78
- end
79
-
80
- # Returns list of ems_refs
81
- # @return [Array<String>]
82
- def references(collection)
83
- manager_refs_by_association.try(:[], collection).try(:[], :ems_ref)&.to_a || []
84
- end
85
-
86
- # Returns list of names
87
- # @return [Array<String>]
88
- def name_references(collection)
89
- manager_refs_by_association.try(:[], collection).try(:[], :name)&.to_a || []
90
- end
91
- end
92
- end