inventory_refresh 0.3.3 → 1.0.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 +25 -30
- data/.github/workflows/ci.yaml +47 -0
- data/.rubocop.yml +3 -3
- data/.rubocop_cc.yml +3 -4
- data/.rubocop_local.yml +5 -2
- data/.whitesource +3 -0
- data/CHANGELOG.md +19 -0
- data/Gemfile +10 -4
- data/README.md +1 -2
- data/Rakefile +2 -2
- data/inventory_refresh.gemspec +9 -10
- data/lib/inventory_refresh/application_record_iterator.rb +25 -12
- data/lib/inventory_refresh/graph/topological_sort.rb +24 -26
- data/lib/inventory_refresh/graph.rb +2 -2
- data/lib/inventory_refresh/inventory_collection/builder.rb +37 -15
- data/lib/inventory_refresh/inventory_collection/data_storage.rb +9 -0
- data/lib/inventory_refresh/inventory_collection/helpers/initialize_helper.rb +147 -38
- data/lib/inventory_refresh/inventory_collection/helpers/questions_helper.rb +49 -5
- data/lib/inventory_refresh/inventory_collection/index/proxy.rb +35 -3
- data/lib/inventory_refresh/inventory_collection/index/type/base.rb +8 -0
- data/lib/inventory_refresh/inventory_collection/index/type/local_db.rb +2 -0
- data/lib/inventory_refresh/inventory_collection/index/type/skeletal.rb +1 -0
- data/lib/inventory_refresh/inventory_collection/reference.rb +1 -0
- data/lib/inventory_refresh/inventory_collection/references_storage.rb +17 -0
- data/lib/inventory_refresh/inventory_collection/scanner.rb +91 -3
- data/lib/inventory_refresh/inventory_collection/serialization.rb +16 -10
- data/lib/inventory_refresh/inventory_collection.rb +122 -64
- data/lib/inventory_refresh/inventory_object.rb +74 -40
- data/lib/inventory_refresh/inventory_object_lazy.rb +17 -10
- data/lib/inventory_refresh/null_logger.rb +2 -2
- data/lib/inventory_refresh/persister.rb +31 -65
- data/lib/inventory_refresh/save_collection/base.rb +4 -2
- data/lib/inventory_refresh/save_collection/saver/base.rb +114 -15
- data/lib/inventory_refresh/save_collection/saver/batch.rb +17 -0
- data/lib/inventory_refresh/save_collection/saver/concurrent_safe_batch.rb +129 -51
- data/lib/inventory_refresh/save_collection/saver/default.rb +57 -0
- data/lib/inventory_refresh/save_collection/saver/partial_upsert_helper.rb +2 -19
- data/lib/inventory_refresh/save_collection/saver/retention_helper.rb +68 -3
- data/lib/inventory_refresh/save_collection/saver/sql_helper.rb +125 -0
- data/lib/inventory_refresh/save_collection/saver/sql_helper_update.rb +10 -6
- data/lib/inventory_refresh/save_collection/saver/sql_helper_upsert.rb +28 -16
- data/lib/inventory_refresh/save_collection/sweeper.rb +17 -93
- data/lib/inventory_refresh/save_collection/topological_sort.rb +5 -5
- data/lib/inventory_refresh/save_inventory.rb +5 -12
- data/lib/inventory_refresh/target.rb +73 -0
- data/lib/inventory_refresh/target_collection.rb +92 -0
- data/lib/inventory_refresh/version.rb +1 -1
- data/lib/inventory_refresh.rb +2 -0
- metadata +42 -39
- data/.travis.yml +0 -23
- data/lib/inventory_refresh/exception.rb +0 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d788fa837920653d4f68b418a41687dcfb5555da780854c371654b93cf0fbaa
|
4
|
+
data.tar.gz: 516547253906ef09089351d6e007ebaac0160aaadee73a38782aa598f284e396
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6b1fcf9600b6f9ff22da8cc5226f7c6395a7c35f9b9b62f9c0a2edb51158e1d3eaa59b1c1400b1e1ccf2f2bf1ff7bfa5901db04326afc490d569715daf73ad9
|
7
|
+
data.tar.gz: 50b1acc7a4b10a5a8a678b16fd06aa9c809068054d9b469391e877e668e18340ca998ab8485346d5f51cd0f682582fcd9ef516df2f88e273c1a401f45fe31241
|
data/.codeclimate.yml
CHANGED
@@ -1,18 +1,21 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
-
|
4
|
-
|
5
|
-
-
|
6
|
-
|
7
|
-
-
|
8
|
-
|
9
|
-
-
|
10
|
-
|
1
|
+
prepare:
|
2
|
+
fetch:
|
3
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_base.yml
|
4
|
+
path: ".rubocop_base.yml"
|
5
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/.rubocop_cc_base.yml
|
6
|
+
path: ".rubocop_cc_base.yml"
|
7
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/base.yml
|
8
|
+
path: styles/base.yml
|
9
|
+
- url: https://raw.githubusercontent.com/ManageIQ/manageiq-style/master/styles/cc_base.yml
|
10
|
+
path: styles/cc_base.yml
|
11
|
+
plugins:
|
12
|
+
rubocop:
|
13
|
+
enabled: true
|
14
|
+
config: ".rubocop_cc.yml"
|
15
|
+
channel: rubocop-0-82
|
11
16
|
brakeman:
|
12
|
-
# very slow :sad_panda:
|
13
17
|
enabled: false
|
14
18
|
bundler-audit:
|
15
|
-
# requires Gemfile.lock
|
16
19
|
enabled: false
|
17
20
|
csslint:
|
18
21
|
enabled: false
|
@@ -24,25 +27,17 @@ engines:
|
|
24
27
|
- javascript
|
25
28
|
eslint:
|
26
29
|
enabled: false
|
27
|
-
channel:
|
30
|
+
channel: eslint-3
|
28
31
|
fixme:
|
29
|
-
# let's enable later
|
30
32
|
enabled: false
|
31
33
|
markdownlint:
|
32
|
-
# let's enable later
|
33
34
|
enabled: false
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
path: ".rubocop_cc_base.yml"
|
44
|
-
ratings:
|
45
|
-
paths:
|
46
|
-
- Gemfile.lock
|
47
|
-
- "**.rake"
|
48
|
-
- "**.rb"
|
35
|
+
exclude_patterns:
|
36
|
+
- ".git/"
|
37
|
+
- "**.xml"
|
38
|
+
- "**.yaml"
|
39
|
+
- "**.yml"
|
40
|
+
- locale/
|
41
|
+
- spec/
|
42
|
+
- tools/
|
43
|
+
version: '2'
|
@@ -0,0 +1,47 @@
|
|
1
|
+
name: CI
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
ci:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
strategy:
|
9
|
+
matrix:
|
10
|
+
ruby-version:
|
11
|
+
- '2.5'
|
12
|
+
- '2.6'
|
13
|
+
- '2.7'
|
14
|
+
rails-version:
|
15
|
+
- '5.2'
|
16
|
+
- '6.0'
|
17
|
+
- '6.1'
|
18
|
+
services:
|
19
|
+
postgres:
|
20
|
+
image: manageiq/postgresql:10
|
21
|
+
env:
|
22
|
+
POSTGRESQL_USER: root
|
23
|
+
POSTGRESQL_PASSWORD: smartvm
|
24
|
+
POSTGRESQL_DATABASE: inventory_refresh_dummy_test
|
25
|
+
options: --health-cmd pg_isready --health-interval 2s --health-timeout 5s --health-retries 5
|
26
|
+
ports:
|
27
|
+
- 5432:5432
|
28
|
+
env:
|
29
|
+
TEST_RAILS_VERSION: ${{ matrix.rails-version }}
|
30
|
+
PGHOST: localhost
|
31
|
+
PGPASSWORD: smartvm
|
32
|
+
CC_TEST_REPORTER_ID: ${{ secrets.CC_TEST_REPORTER_ID }}
|
33
|
+
steps:
|
34
|
+
- uses: actions/checkout@v2
|
35
|
+
- name: Set up Ruby
|
36
|
+
uses: ruby/setup-ruby@v1
|
37
|
+
with:
|
38
|
+
ruby-version: ${{ matrix.ruby-version }}
|
39
|
+
bundler-cache: true
|
40
|
+
- name: Prepare tests
|
41
|
+
run: bundle exec rake spec:setup
|
42
|
+
- name: Run tests
|
43
|
+
run: bundle exec rake
|
44
|
+
- name: Report code coverage
|
45
|
+
if: ${{ github.ref == 'refs/heads/master' && matrix.ruby-version == '2.7' && matrix.rails-version == '6.1' }}
|
46
|
+
continue-on-error: true
|
47
|
+
uses: paambaati/codeclimate-action@v3.0.0
|
data/.rubocop.yml
CHANGED
@@ -1,4 +1,4 @@
|
|
1
1
|
inherit_from:
|
2
|
-
-
|
3
|
-
|
4
|
-
- .
|
2
|
+
- ".rubocop_local.yml"
|
3
|
+
inherit_gem:
|
4
|
+
manageiq-style: ".rubocop_base.yml"
|
data/.rubocop_cc.yml
CHANGED
data/.rubocop_local.yml
CHANGED
data/.whitesource
ADDED
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
# Changelog
|
2
|
+
|
3
|
+
All notable changes to this project will be documented in this file.
|
4
|
+
This project adheres to [Semantic Versioning](http://semver.org/).
|
5
|
+
|
6
|
+
## [Unreleased]
|
7
|
+
|
8
|
+
## [1.0.0] - 2022-02-09
|
9
|
+
### Changed
|
10
|
+
- Run rubocop -A (#102)
|
11
|
+
- Switch from travis to github actions (#104, #105)
|
12
|
+
|
13
|
+
### Added
|
14
|
+
- **BREAKING** Add back support for non-concurrent-safe batch strategies (#101)
|
15
|
+
- Add support for Rails 6.1 (#103)
|
16
|
+
- Add bundler-inject (#106)
|
17
|
+
|
18
|
+
### Fixed
|
19
|
+
- Fix InventoryCollection missing cache returns (#107)
|
data/Gemfile
CHANGED
@@ -1,10 +1,16 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
|
3
|
+
plugin "bundler-inject", "~> 2.0"
|
4
|
+
require File.join(Bundler::Plugin.index.load_paths("bundler-inject")[0], "bundler-inject") rescue nil
|
4
5
|
|
5
6
|
# Specify your gem's dependencies in inventory_refresh.gemspec
|
6
7
|
gemspec
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
case ENV['TEST_RAILS_VERSION']
|
10
|
+
when "5.2"
|
11
|
+
gem "activerecord", "~>5.2.6"
|
12
|
+
when "6.0"
|
13
|
+
gem "activerecord", "~>6.0.4"
|
14
|
+
when "6.1"
|
15
|
+
gem "activerecord", "~>6.1.4"
|
16
|
+
end
|
data/README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# InventoryRefresh
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/inventory_refresh.svg)](http://badge.fury.io/rb/inventory_refresh)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/ManageIQ/inventory_refresh/actions/workflows/ci.yaml/badge.svg)](https://github.com/ManageIQ/inventory_refresh/actions/workflows/ci.yaml)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/ManageIQ/inventory_refresh.svg)](https://codeclimate.com/github/ManageIQ/inventory_refresh)
|
6
6
|
[![Test Coverage](https://codeclimate.com/github/ManageIQ/inventory_refresh/badges/coverage.svg)](https://codeclimate.com/github/ManageIQ/inventory_refresh/coverage)
|
7
|
-
[![Security](https://hakiri.io/github/ManageIQ/inventory_refresh/master.svg)](https://hakiri.io/github/ManageIQ/inventory_refresh/master)
|
8
7
|
|
9
8
|
[![Chat](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ManageIQ/manageiq/providers?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
10
9
|
|
data/Rakefile
CHANGED
@@ -12,7 +12,7 @@ namespace :spec do
|
|
12
12
|
|
13
13
|
task :db_load_schema do
|
14
14
|
require "active_record"
|
15
|
-
with_connection(test_database_name) { load File.join(__dir__, %w
|
15
|
+
with_connection(test_database_name) { load File.join(__dir__, %w[spec schema.rb]) }
|
16
16
|
end
|
17
17
|
|
18
18
|
desc "Setup test database"
|
@@ -20,7 +20,7 @@ namespace :spec do
|
|
20
20
|
|
21
21
|
def connection_spec
|
22
22
|
require 'yaml'
|
23
|
-
@connection_spec ||= YAML.load_file(File.join(__dir__, %w
|
23
|
+
@connection_spec ||= YAML.load_file(File.join(__dir__, %w[config database.yml]))
|
24
24
|
end
|
25
25
|
|
26
26
|
def test_database_name
|
data/inventory_refresh.gemspec
CHANGED
@@ -1,5 +1,4 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path("../lib", __FILE__)
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
3
|
require "inventory_refresh/version"
|
5
4
|
|
@@ -8,30 +7,30 @@ Gem::Specification.new do |spec|
|
|
8
7
|
spec.version = InventoryRefresh::VERSION
|
9
8
|
spec.authors = ["ManageIQ Developers"]
|
10
9
|
|
11
|
-
spec.summary =
|
12
|
-
spec.description =
|
10
|
+
spec.summary = 'Topological Inventory Persister'
|
11
|
+
spec.description = 'Topological Inventory Persister'
|
13
12
|
spec.homepage = "https://github.com/ManageIQ/inventory_refresh"
|
14
13
|
spec.licenses = ["Apache-2.0"]
|
15
14
|
|
16
15
|
# Specify which files should be added to the gem when it is released.
|
17
16
|
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
18
|
-
spec.files = Dir.chdir(File.expand_path(
|
17
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
19
18
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
19
|
end
|
21
20
|
spec.bindir = "exe"
|
22
21
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
23
22
|
spec.require_paths = ["lib"]
|
23
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
24
24
|
|
25
|
-
spec.add_dependency "activerecord", "
|
26
|
-
spec.add_dependency "more_core_extensions", "
|
25
|
+
spec.add_dependency "activerecord", ">=5.0", "< 7.0"
|
26
|
+
spec.add_dependency "more_core_extensions", ">=3.5", "< 5"
|
27
27
|
spec.add_dependency "pg", "> 0"
|
28
28
|
|
29
29
|
spec.add_development_dependency "ancestry"
|
30
30
|
spec.add_development_dependency "bundler", "~> 2.0"
|
31
31
|
spec.add_development_dependency "factory_bot", "~> 4.11.1"
|
32
|
+
spec.add_development_dependency "manageiq-style"
|
32
33
|
spec.add_development_dependency "rake", "~> 10.0"
|
33
34
|
spec.add_development_dependency "rspec", "~> 3.0"
|
34
|
-
spec.add_development_dependency "
|
35
|
-
spec.add_development_dependency "rubocop-performance"
|
36
|
-
spec.add_development_dependency "simplecov"
|
35
|
+
spec.add_development_dependency "simplecov", ">= 0.21.2"
|
37
36
|
end
|
@@ -1,12 +1,20 @@
|
|
1
1
|
module InventoryRefresh
|
2
2
|
class ApplicationRecordIterator
|
3
|
-
attr_reader :inventory_collection
|
3
|
+
attr_reader :inventory_collection, :manager_uuids_set, :iterator, :query
|
4
4
|
|
5
|
-
# An iterator that can fetch batches of the AR objects based on a set of
|
5
|
+
# An iterator that can fetch batches of the AR objects based on a set of manager refs, or just mimics AR relation
|
6
|
+
# when given an iterator. Or given query, acts as iterator by selecting batches.
|
6
7
|
#
|
7
8
|
# @param inventory_collection [InventoryRefresh::InventoryCollection] Inventory collection owning the iterator
|
8
|
-
|
9
|
+
# @param manager_uuids_set [Array<InventoryRefresh::InventoryCollection::Reference>] Array of references we want to
|
10
|
+
# fetch from the DB
|
11
|
+
# @param iterator [Proc] Block based iterator
|
12
|
+
# @query query [ActiveRecord::Relation] Existing query we want to use for querying the db
|
13
|
+
def initialize(inventory_collection: nil, manager_uuids_set: nil, iterator: nil, query: nil)
|
9
14
|
@inventory_collection = inventory_collection
|
15
|
+
@manager_uuids_set = manager_uuids_set
|
16
|
+
@iterator = iterator
|
17
|
+
@query = query
|
10
18
|
end
|
11
19
|
|
12
20
|
# Iterator that mimics find_in_batches of ActiveRecord::Relation. This iterator serves for making more optimized query
|
@@ -17,22 +25,27 @@ module InventoryRefresh
|
|
17
25
|
# and relation.where(:id => 500ids)
|
18
26
|
#
|
19
27
|
# @param batch_size [Integer] A batch size we want to fetch from DB
|
20
|
-
# @param attributes_index [Hash{String => Hash}] Indexed hash with data we will be saving
|
21
28
|
# @yield Code processing the batches
|
22
|
-
def find_in_batches(batch_size: 1000,
|
23
|
-
|
24
|
-
|
29
|
+
def find_in_batches(batch_size: 1000, &block)
|
30
|
+
if iterator
|
31
|
+
iterator.call(&block)
|
32
|
+
elsif query
|
33
|
+
manager_uuids_set.each_slice(batch_size) do |batch|
|
34
|
+
yield(query.where(inventory_collection.targeted_selection_for(batch)))
|
35
|
+
end
|
36
|
+
else
|
37
|
+
manager_uuids_set.each_slice(batch_size) do |batch|
|
38
|
+
yield(inventory_collection.db_collection_for_comparison_for(batch))
|
39
|
+
end
|
25
40
|
end
|
26
41
|
end
|
27
42
|
|
28
43
|
# Iterator that mimics find_each of ActiveRecord::Relation using find_in_batches (see #find_in_batches)
|
29
44
|
#
|
30
45
|
# @yield Code processing the batches
|
31
|
-
def find_each(
|
32
|
-
find_in_batches
|
33
|
-
batch.each
|
34
|
-
yield(item)
|
35
|
-
end
|
46
|
+
def find_each(&block)
|
47
|
+
find_in_batches do |batch|
|
48
|
+
batch.each(&block)
|
36
49
|
end
|
37
50
|
end
|
38
51
|
end
|
@@ -8,30 +8,30 @@ module InventoryRefresh
|
|
8
8
|
@graph = graph
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
11
|
+
################################################################################################################
|
12
|
+
# Topological sort of the graph of the DTO collections to find the right order of saving DTO collections and
|
13
|
+
# identify what DTO collections can be saved in parallel.
|
14
|
+
# Does not mutate graph.
|
15
|
+
#
|
16
|
+
# @return [Array<Array>] Array of arrays(layers) of InventoryCollection objects
|
17
|
+
################################################################################################################
|
18
|
+
# The expected input here is the directed acyclic Graph G (inventory_collections), consisting of Vertices(Nodes) V and
|
19
|
+
# Edges E:
|
20
|
+
# G = (V, E)
|
21
|
+
#
|
22
|
+
# The directed edge is defined as (u, v), where u is the dependency of v, i.e. arrow comes from u to v:
|
23
|
+
# (u, v) ∈ E and u,v ∈ V
|
24
|
+
#
|
25
|
+
# S0 is a layer that has no dependencies:
|
26
|
+
# S0 = { v ∈ V ∣ ∀u ∈ V.(u,v) ∉ E}
|
27
|
+
#
|
28
|
+
# Si+1 is a layer whose dependencies are in the sum of the previous layers from i to 0, cannot write
|
29
|
+
# mathematical sum using U in text editor, so there is an alternative format using _(sum)
|
30
|
+
# Si+1 = { v ∈ V ∣ ∀u ∈ V.(u,v) ∈ E → u ∈ _(sum(S0..Si))_ }
|
31
|
+
#
|
32
|
+
# Then each Si can have their Vertices(DTO collections) processed in parallel. This algorithm cannot
|
33
|
+
# identify independent sub-graphs inside of the layers Si, so we can make the processing even more effective.
|
34
|
+
################################################################################################################
|
35
35
|
def topological_sort
|
36
36
|
nodes = graph.nodes.dup
|
37
37
|
edges = graph.edges
|
@@ -45,14 +45,12 @@ module InventoryRefresh
|
|
45
45
|
max_depth -= 1
|
46
46
|
if max_depth <= 0
|
47
47
|
message = "Max depth reached while doing topological sort, your graph probably contains a cycle"
|
48
|
-
#logger.error("#{message}:\n#{graph.to_graphviz}")
|
49
48
|
raise "#{message} (see log)"
|
50
49
|
end
|
51
50
|
|
52
51
|
set, nodes = nodes.partition { |v| edges.select { |e| e.second == v }.all? { |e| sets.flatten.include?(e.first) } }
|
53
52
|
if set.blank?
|
54
53
|
message = "Blank dependency set while doing topological sort, your graph probably contains a cycle"
|
55
|
-
#logger.error("#{message}:\n#{graph.to_graphviz}")
|
56
54
|
raise "#{message} (see log)"
|
57
55
|
end
|
58
56
|
|
@@ -37,7 +37,7 @@ module InventoryRefresh
|
|
37
37
|
s << " #{node_names[from]} -> #{node_names[to]};"
|
38
38
|
end
|
39
39
|
s << "}"
|
40
|
-
s.join("\n")
|
40
|
+
"#{s.join("\n")}\n"
|
41
41
|
end
|
42
42
|
|
43
43
|
protected
|
@@ -147,7 +147,7 @@ module InventoryRefresh
|
|
147
147
|
nodes.group_by { |n| n.respond_to?(:name) ? n.name.to_s : n.to_s }.each do |base_name, ns|
|
148
148
|
ns.each_with_index do |n, i|
|
149
149
|
name = ns.size == 1 ? base_name : "#{base_name}_#{i}"
|
150
|
-
name =
|
150
|
+
name = "\"#{name.gsub(/["\\]/) { |c| "\\#{c}" }}\"" unless /^[A-Za-z0-9_]+$/.match?(name)
|
151
151
|
node_names[n] = name
|
152
152
|
end
|
153
153
|
end
|
@@ -4,17 +4,39 @@ module InventoryRefresh
|
|
4
4
|
class MissingModelClassError < StandardError; end
|
5
5
|
|
6
6
|
def self.allowed_properties
|
7
|
-
%i
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
7
|
+
%i[
|
8
|
+
all_manager_uuids
|
9
|
+
arel
|
10
|
+
association
|
11
|
+
attributes_blacklist
|
12
|
+
attributes_whitelist
|
13
|
+
batch_extra_attributes
|
14
|
+
complete
|
15
|
+
create_only
|
16
|
+
custom_save_block
|
17
|
+
custom_reconnect_block
|
18
|
+
default_values
|
19
|
+
delete_method
|
20
|
+
dependency_attributes
|
21
|
+
check_changed
|
22
|
+
inventory_object_attributes
|
23
|
+
manager_ref
|
24
|
+
manager_ref_allowed_nil
|
25
|
+
manager_uuids
|
26
|
+
model_class
|
27
|
+
name
|
28
|
+
parent
|
29
|
+
parent_inventory_collections
|
30
|
+
retention_strategy
|
31
|
+
strategy
|
32
|
+
saver_strategy
|
33
|
+
secondary_refs
|
34
|
+
targeted
|
35
|
+
targeted_arel
|
36
|
+
update_only
|
37
|
+
use_ar_object
|
38
|
+
assert_graph_integrity
|
39
|
+
].to_set
|
18
40
|
end
|
19
41
|
|
20
42
|
def allowed_properties
|
@@ -76,8 +98,8 @@ module InventoryRefresh
|
|
76
98
|
|
77
99
|
send(@name.to_sym) if @name.respond_to?(:to_sym) && respond_to?(@name.to_sym)
|
78
100
|
|
79
|
-
if @properties[:model_class].nil?
|
80
|
-
add_properties(:model_class => auto_model_class)
|
101
|
+
if @properties[:model_class].nil? && !(@options[:without_model_class])
|
102
|
+
add_properties(:model_class => auto_model_class)
|
81
103
|
end
|
82
104
|
end
|
83
105
|
|
@@ -177,7 +199,7 @@ module InventoryRefresh
|
|
177
199
|
|
178
200
|
def assert_allowed_property(name)
|
179
201
|
unless allowed_properties.include?(name)
|
180
|
-
raise "InventoryCollection property :#{name} is not allowed. Allowed properties are:\n#{
|
202
|
+
raise "InventoryCollection property :#{name} is not allowed. Allowed properties are:\n#{allowed_properties.to_a.map(&:to_s).join(', ')}"
|
181
203
|
end
|
182
204
|
end
|
183
205
|
|
@@ -216,7 +238,7 @@ module InventoryRefresh
|
|
216
238
|
def auto_inventory_attributes
|
217
239
|
return if @properties[:model_class].nil?
|
218
240
|
|
219
|
-
(@properties[:model_class].new.methods - ar_base_class.methods).grep(
|
241
|
+
(@properties[:model_class].new.methods - ar_base_class.methods).grep(/^\w+?=$/).collect do |setter|
|
220
242
|
setter.to_s[0..setter.length - 2].to_sym
|
221
243
|
end
|
222
244
|
end
|
@@ -70,6 +70,15 @@ module InventoryRefresh
|
|
70
70
|
build(hash)
|
71
71
|
end
|
72
72
|
|
73
|
+
# Finds InventoryObject.
|
74
|
+
#
|
75
|
+
# @param hash [Hash] Hash that needs to contain attributes defined in :manager_ref of the InventoryCollection
|
76
|
+
# @return [InventoryRefresh::InventoryObject] Found or built InventoryObject object
|
77
|
+
def find_in_data(hash)
|
78
|
+
_hash, _uuid, inventory_object = primary_index_scan(hash)
|
79
|
+
inventory_object
|
80
|
+
end
|
81
|
+
|
73
82
|
# Finds of builds a new InventoryObject. By building it, we also put in into the InventoryCollection's storage.
|
74
83
|
#
|
75
84
|
# @param hash [Hash] Hash that needs to contain attributes defined in :manager_ref of the
|