inventory_refresh 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +2 -4
  5. data/lib/inventory_refresh.rb +0 -2
  6. data/lib/inventory_refresh/application_record_iterator.rb +9 -26
  7. data/lib/inventory_refresh/exception.rb +8 -0
  8. data/lib/inventory_refresh/inventory_collection.rb +36 -110
  9. data/lib/inventory_refresh/inventory_collection/builder.rb +6 -6
  10. data/lib/inventory_refresh/inventory_collection/data_storage.rb +0 -9
  11. data/lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb +34 -143
  12. data/lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb +1 -44
  13. data/lib/inventory_refresh/inventory_collection/index/proxy.rb +6 -34
  14. data/lib/inventory_refresh/inventory_collection/index/type/base.rb +0 -8
  15. data/lib/inventory_refresh/inventory_collection/references_storage.rb +0 -17
  16. data/lib/inventory_refresh/inventory_collection/scanner.rb +1 -87
  17. data/lib/inventory_refresh/inventory_collection/serialization.rb +10 -16
  18. data/lib/inventory_refresh/inventory_object.rb +34 -68
  19. data/lib/inventory_refresh/inventory_object_lazy.rb +10 -17
  20. data/lib/inventory_refresh/persister.rb +63 -29
  21. data/lib/inventory_refresh/save_collection/base.rb +2 -4
  22. data/lib/inventory_refresh/save_collection/saver/base.rb +8 -108
  23. data/lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb +48 -126
  24. data/lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb +19 -1
  25. data/lib/inventory_refresh/save_collection/saver/retention_helper.rb +3 -68
  26. data/lib/inventory_refresh/save_collection/saver/sql_helper.rb +0 -125
  27. data/lib/inventory_refresh/save_collection/saver/sql_helper_update.rb +5 -9
  28. data/lib/inventory_refresh/save_collection/saver/sql_helper_upsert.rb +9 -17
  29. data/lib/inventory_refresh/save_collection/sweeper.rb +91 -18
  30. data/lib/inventory_refresh/save_collection/topological_sort.rb +5 -5
  31. data/lib/inventory_refresh/save_inventory.rb +12 -5
  32. data/lib/inventory_refresh/version.rb +1 -1
  33. metadata +9 -45
  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
@@ -17,21 +17,21 @@ module InventoryRefresh::SaveCollection
17
17
 
18
18
  layers = InventoryRefresh::Graph::TopologicalSort.new(graph).topological_sort
19
19
 
20
- logger.debug("Saving manager #{ems.name}...")
20
+ logger.debug("Saving manager #{ems.id}...")
21
21
 
22
- sorted_graph_log = "Topological sorting of manager #{ems.name} resulted in these layers processable in parallel:\n"
22
+ sorted_graph_log = "Topological sorting of manager #{ems.id} resulted in these layers processable in parallel:\n"
23
23
  sorted_graph_log += graph.to_graphviz(:layers => layers)
24
24
  logger.debug(sorted_graph_log)
25
25
 
26
26
  layers.each_with_index do |layer, index|
27
- logger.debug("Saving manager #{ems.name} | Layer #{index}")
27
+ logger.debug("Saving manager #{ems.id} | Layer #{index}")
28
28
  layer.each do |inventory_collection|
29
29
  save_inventory_object_inventory(ems, inventory_collection) unless inventory_collection.saved?
30
30
  end
31
- logger.debug("Saved manager #{ems.name} | Layer #{index}")
31
+ logger.debug("Saved manager #{ems.id} | Layer #{index}")
32
32
  end
33
33
 
34
- logger.debug("Saving manager #{ems.name}...Complete")
34
+ logger.debug("Saving manager #{ems.id}...Complete")
35
35
  end
36
36
  end
37
37
  end
@@ -29,11 +29,18 @@ module InventoryRefresh
29
29
  # @param ems [ExtManagementSystem] manager owning the inventory_collections
30
30
  # @param inventory_collections [Array<InventoryRefresh::InventoryCollection>] array of InventoryCollection objects
31
31
  # for sweeping
32
+ # @param sweep_scope [Array<String, Symbol, Hash>] Array of inventory collection names marking sweep. Or for
33
+ # targeted sweeping it's array of hashes, where key is inventory collection name pointing to an array of
34
+ # identifiers of inventory objects we want to target for sweeping.
32
35
  # @param refresh_state [ActiveRecord] Record of :refresh_states
33
- def sweep_inactive_records(ems, inventory_collections, refresh_state)
34
- logger.info("#{log_header(ems)} Sweeping EMS Inventory...")
35
- InventoryRefresh::SaveCollection::Sweeper.sweep(ems, inventory_collections, refresh_state)
36
- logger.info("#{log_header(ems)} Sweeping EMS Inventory...Complete")
36
+ def sweep_inactive_records(ems, inventory_collections, sweep_scope, refresh_state)
37
+ inventory_collections.each do |inventory_collection|
38
+ inventory_collection.strategy = :local_db_find_references
39
+ end
40
+
41
+ logger.info("#{log_header(ems)} Sweeping EMS Inventory with scope #{sweep_scope} and date #{refresh_state.created_at} ...")
42
+ InventoryRefresh::SaveCollection::Sweeper.sweep(ems, inventory_collections, sweep_scope, refresh_state)
43
+ logger.info("#{log_header(ems)} Sweeping EMS Inventory with scope #{sweep_scope} and date #{refresh_state.created_at}...Complete")
37
44
 
38
45
  ems
39
46
  end
@@ -43,7 +50,7 @@ module InventoryRefresh
43
50
  # @param ems [ExtManagementSystem] manager owning the inventory_collections
44
51
  # @return [String] helper string for logging
45
52
  def log_header(ems)
46
- "EMS: [#{ems.name}], id: [#{ems.id}]"
53
+ "EMS: [#{ems.id}]"
47
54
  end
48
55
  end
49
56
  end
@@ -1,3 +1,3 @@
1
1
  module InventoryRefresh
2
- VERSION = "0.2.2".freeze
2
+ VERSION = "0.3.0".freeze
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: inventory_refresh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ManageIQ Developers
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-14 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
@@ -28,22 +28,16 @@ dependencies:
28
28
  name: more_core_extensions
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '3.5'
34
- - - "<"
35
- - !ruby/object:Gem::Version
36
- version: '5'
37
34
  type: :runtime
38
35
  prerelease: false
39
36
  version_requirements: !ruby/object:Gem::Requirement
40
37
  requirements:
41
- - - ">="
38
+ - - "~>"
42
39
  - !ruby/object:Gem::Version
43
40
  version: '3.5'
44
- - - "<"
45
- - !ruby/object:Gem::Version
46
- version: '5'
47
41
  - !ruby/object:Gem::Dependency
48
42
  name: pg
49
43
  requirement: !ruby/object:Gem::Requirement
@@ -78,14 +72,14 @@ dependencies:
78
72
  requirements:
79
73
  - - "~>"
80
74
  - !ruby/object:Gem::Version
81
- version: '2.0'
75
+ version: 2.0.1
82
76
  type: :development
83
77
  prerelease: false
84
78
  version_requirements: !ruby/object:Gem::Requirement
85
79
  requirements:
86
80
  - - "~>"
87
81
  - !ruby/object:Gem::Version
88
- version: '2.0'
82
+ version: 2.0.1
89
83
  - !ruby/object:Gem::Dependency
90
84
  name: factory_bot
91
85
  requirement: !ruby/object:Gem::Requirement
@@ -128,34 +122,6 @@ dependencies:
128
122
  - - "~>"
129
123
  - !ruby/object:Gem::Version
130
124
  version: '3.0'
131
- - !ruby/object:Gem::Dependency
132
- name: rubocop
133
- requirement: !ruby/object:Gem::Requirement
134
- requirements:
135
- - - ">="
136
- - !ruby/object:Gem::Version
137
- version: '0'
138
- type: :development
139
- prerelease: false
140
- version_requirements: !ruby/object:Gem::Requirement
141
- requirements:
142
- - - ">="
143
- - !ruby/object:Gem::Version
144
- version: '0'
145
- - !ruby/object:Gem::Dependency
146
- name: rubocop-performance
147
- requirement: !ruby/object:Gem::Requirement
148
- requirements:
149
- - - ">="
150
- - !ruby/object:Gem::Version
151
- version: '0'
152
- type: :development
153
- prerelease: false
154
- version_requirements: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - ">="
157
- - !ruby/object:Gem::Version
158
- version: '0'
159
125
  - !ruby/object:Gem::Dependency
160
126
  name: simplecov
161
127
  requirement: !ruby/object:Gem::Requirement
@@ -198,6 +164,7 @@ files:
198
164
  - lib/inventory_refresh.rb
199
165
  - lib/inventory_refresh/application_record_iterator.rb
200
166
  - lib/inventory_refresh/application_record_reference.rb
167
+ - lib/inventory_refresh/exception.rb
201
168
  - lib/inventory_refresh/graph.rb
202
169
  - lib/inventory_refresh/graph/topological_sort.rb
203
170
  - lib/inventory_refresh/inventory_collection.rb
@@ -225,9 +192,7 @@ files:
225
192
  - lib/inventory_refresh/persister.rb
226
193
  - lib/inventory_refresh/save_collection/base.rb
227
194
  - lib/inventory_refresh/save_collection/saver/base.rb
228
- - lib/inventory_refresh/save_collection/saver/batch.rb
229
195
  - lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb
230
- - lib/inventory_refresh/save_collection/saver/default.rb
231
196
  - lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb
232
197
  - lib/inventory_refresh/save_collection/saver/retention_helper.rb
233
198
  - lib/inventory_refresh/save_collection/saver/sql_helper.rb
@@ -236,8 +201,6 @@ files:
236
201
  - lib/inventory_refresh/save_collection/sweeper.rb
237
202
  - lib/inventory_refresh/save_collection/topological_sort.rb
238
203
  - lib/inventory_refresh/save_inventory.rb
239
- - lib/inventory_refresh/target.rb
240
- - lib/inventory_refresh/target_collection.rb
241
204
  - lib/inventory_refresh/version.rb
242
205
  homepage: https://github.com/ManageIQ/inventory_refresh
243
206
  licenses:
@@ -258,7 +221,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
258
221
  - !ruby/object:Gem::Version
259
222
  version: '0'
260
223
  requirements: []
261
- rubygems_version: 3.1.3
224
+ rubyforge_project:
225
+ rubygems_version: 2.7.6.2
262
226
  signing_key:
263
227
  specification_version: 4
264
228
  summary: Topological Inventory Persister
@@ -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