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