inventory_refresh 0.2.3 → 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.
- checksums.yaml +4 -4
- data/.codeclimate.yml +0 -1
- data/.travis.yml +6 -8
- data/inventory_refresh.gemspec +3 -5
- data/lib/inventory_refresh/application_record_iterator.rb +9 -26
- data/lib/inventory_refresh/exception.rb +8 -0
- data/lib/inventory_refresh/inventory_collection/builder.rb +6 -6
- data/lib/inventory_refresh/inventory_collection/data_storage.rb +0 -9
- data/lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb +35 -144
- data/lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb +1 -44
- data/lib/inventory_refresh/inventory_collection/index/proxy.rb +6 -34
- data/lib/inventory_refresh/inventory_collection/index/type/base.rb +0 -8
- data/lib/inventory_refresh/inventory_collection/references_storage.rb +0 -17
- data/lib/inventory_refresh/inventory_collection/scanner.rb +1 -87
- data/lib/inventory_refresh/inventory_collection/serialization.rb +10 -16
- data/lib/inventory_refresh/inventory_collection.rb +36 -110
- data/lib/inventory_refresh/inventory_object.rb +34 -68
- data/lib/inventory_refresh/inventory_object_lazy.rb +10 -17
- data/lib/inventory_refresh/persister.rb +63 -29
- data/lib/inventory_refresh/save_collection/base.rb +2 -4
- data/lib/inventory_refresh/save_collection/saver/base.rb +8 -108
- data/lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb +48 -126
- data/lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb +19 -1
- data/lib/inventory_refresh/save_collection/saver/retention_helper.rb +3 -68
- data/lib/inventory_refresh/save_collection/saver/sql_helper.rb +0 -125
- data/lib/inventory_refresh/save_collection/saver/sql_helper_update.rb +5 -9
- data/lib/inventory_refresh/save_collection/saver/sql_helper_upsert.rb +9 -17
- data/lib/inventory_refresh/save_collection/sweeper.rb +91 -18
- data/lib/inventory_refresh/save_collection/topological_sort.rb +5 -5
- data/lib/inventory_refresh/save_inventory.rb +12 -5
- data/lib/inventory_refresh/version.rb +1 -1
- data/lib/inventory_refresh.rb +0 -2
- metadata +15 -57
- data/lib/inventory_refresh/save_collection/saver/batch.rb +0 -17
- data/lib/inventory_refresh/save_collection/saver/default.rb +0 -57
- data/lib/inventory_refresh/target.rb +0 -73
- 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.
|
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:
|
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:
|
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:
|
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
|
-
|
268
|
-
|
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
|