maestrano-connector-rails 2.0.2.pre.RC5 → 2.0.2.pre.RC6
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/.rubocop_todo.yml +4 -0
- data/Gemfile +2 -2
- data/VERSION +1 -1
- data/app/models/maestrano/connector/rails/concerns/entity.rb +3 -125
- data/app/models/maestrano/connector/rails/concerns/sub_entity_base.rb +0 -8
- data/app/models/maestrano/connector/rails/organization.rb +2 -2
- data/app/models/maestrano/connector/rails/services/data_consolidator.rb +157 -0
- data/maestrano-connector-rails.gemspec +10 -12
- data/spec/models/complex_entity_spec.rb +3 -5
- data/spec/spec_helper.rb +1 -1
- metadata +20 -23
- data/bin/rails +0 -17
- data/bin/rake +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44c8a03cd21fe3a99e6db9afaef6859ec8f7a7bf
|
4
|
+
data.tar.gz: fc34a1cec7f51613576f15631b0a1b2f99e3f0e7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 44d8478e4cd319ffa2dd858849b6382d8204f8047071139c817a0cfd0742e95cc4c29b4dba413228eae1eb3a881525924ee5c3b1ee408e6fc2629395c6229348
|
7
|
+
data.tar.gz: 9b77f64bce1e3f2b74b69e7653e36cd2a9aed844992cb6a019847fc657337f0fde563ed4bba96761cb5a241dfa2c0ce0017c55dd11890e8ceb2fc61ff0eaf97b
|
data/.rubocop_todo.yml
CHANGED
data/Gemfile
CHANGED
@@ -3,7 +3,7 @@ source 'http://rubygems.org'
|
|
3
3
|
# Add dependencies required to use your gem here.
|
4
4
|
gem 'rails', '~> 4.2'
|
5
5
|
|
6
|
-
gem 'maestrano-rails', '~> 1.0.
|
6
|
+
gem 'maestrano-rails', '~> 1.0.3'
|
7
7
|
|
8
8
|
gem 'attr_encrypted', '~> 1.4.0'
|
9
9
|
gem 'autoprefixer-rails'
|
@@ -22,7 +22,6 @@ gem 'slim'
|
|
22
22
|
|
23
23
|
# Add dependencies to develop your gem here.
|
24
24
|
group :development do
|
25
|
-
gem 'webmock', '~> 1.24.1'
|
26
25
|
gem 'activerecord-jdbcsqlite3-adapter', platforms: :jruby
|
27
26
|
gem 'bundler'
|
28
27
|
gem 'factory_girl_rails'
|
@@ -36,4 +35,5 @@ group :development do
|
|
36
35
|
gem 'simplecov', '>= 0'
|
37
36
|
gem 'sqlite3', platforms: :ruby
|
38
37
|
gem 'timecop'
|
38
|
+
gem 'webmock', '~> 1.24.1'
|
39
39
|
end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
2.0.2.pre.
|
1
|
+
2.0.2.pre.RC6
|
@@ -422,84 +422,15 @@ module Maestrano::Connector::Rails::Concerns::Entity
|
|
422
422
|
end
|
423
423
|
|
424
424
|
def consolidate_and_map_connec_entities(connec_entities, external_entities, references, external_entity_name)
|
425
|
-
|
426
|
-
# Entity has been created before date filtering limit
|
427
|
-
next nil if before_date_filtering_limit?(entity, false) && !@opts[:full_sync]
|
428
|
-
|
429
|
-
# Unfold the id arrays
|
430
|
-
# From that point on, the connec_entity contains only string of external ids
|
431
|
-
unfold_hash = Maestrano::Connector::Rails::ConnecHelper.unfold_references(entity, references, @organization)
|
432
|
-
entity = unfold_hash[:entity]
|
433
|
-
next nil unless entity # discard if at least one record reference is missing
|
434
|
-
connec_id = unfold_hash[:connec_id]
|
435
|
-
id_refs_only_connec_entity = unfold_hash[:id_refs_only_connec_entity]
|
436
|
-
|
437
|
-
if entity['id'].blank?
|
438
|
-
# Expecting find_or_create to be mostly a create
|
439
|
-
idmap = self.class.find_or_create_idmap(organization_id: @organization.id, name: self.class.object_name_from_connec_entity_hash(entity), external_entity: external_entity_name.downcase, connec_id: connec_id)
|
440
|
-
next map_connec_entity_with_idmap(entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
441
|
-
end
|
442
|
-
|
443
|
-
# Expecting find_or_create to be mostly a find
|
444
|
-
idmap = self.class.find_or_create_idmap(external_id: entity['id'], organization_id: @organization.id, external_entity: external_entity_name.downcase, connec_id: connec_id)
|
445
|
-
idmap.update(name: self.class.object_name_from_connec_entity_hash(entity))
|
446
|
-
|
447
|
-
next nil if idmap.external_inactive || !idmap.to_external || (!@opts[:full_sync] && not_modified_since_last_push_to_external?(idmap, entity))
|
448
|
-
|
449
|
-
# Check for conflict with entities from external
|
450
|
-
solve_conflict(entity, external_entities, external_entity_name, idmap, id_refs_only_connec_entity)
|
451
|
-
}.compact
|
425
|
+
Maestrano::Connector::Rails::Services::DataConsolidator.new(@organization, self, @opts).consolidate_connec_entities(connec_entities, external_entities, references, external_entity_name)
|
452
426
|
end
|
453
427
|
|
454
428
|
def consolidate_and_map_external_entities(external_entities, connec_entity_name)
|
455
|
-
|
456
|
-
# Entity has been created before date filtering limit
|
457
|
-
next nil if before_date_filtering_limit?(entity) && !@opts[:full_sync]
|
458
|
-
|
459
|
-
entity_id = self.class.id_from_external_entity_hash(entity)
|
460
|
-
idmap = self.class.find_or_create_idmap(external_id: entity_id, organization_id: @organization.id, connec_entity: connec_entity_name.downcase)
|
461
|
-
|
462
|
-
# Not pushing entity to Connec!
|
463
|
-
next nil unless idmap.to_connec
|
464
|
-
|
465
|
-
# Not pushing to Connec! and flagging as inactive if inactive in external application
|
466
|
-
inactive = self.class.inactive_from_external_entity_hash?(entity)
|
467
|
-
idmap.update(external_inactive: inactive, name: self.class.object_name_from_external_entity_hash(entity))
|
468
|
-
next nil if inactive
|
469
|
-
|
470
|
-
# Entity has not been modified since its last push to connec!
|
471
|
-
next nil if !@opts[:full_sync] && not_modified_since_last_push_to_connec?(idmap, entity)
|
472
|
-
|
473
|
-
map_external_entity_with_idmap(entity, connec_entity_name, idmap)
|
474
|
-
}.compact
|
429
|
+
Maestrano::Connector::Rails::Services::DataConsolidator.new(@organization, self, @opts).consolidate_external_entities(external_entities, connec_entity_name)
|
475
430
|
end
|
476
431
|
|
477
432
|
def consolidate_and_map_singleton(connec_entities, external_entities)
|
478
|
-
|
479
|
-
|
480
|
-
idmap = self.class.find_or_create_idmap(organization_id: @organization.id)
|
481
|
-
# No to_connec, to_external and inactive consideration here as we don't expect those workflow for singleton
|
482
|
-
|
483
|
-
keep_external = if external_entities.empty?
|
484
|
-
false
|
485
|
-
elsif connec_entities.empty?
|
486
|
-
true
|
487
|
-
elsif @opts.key?(:connec_preemption)
|
488
|
-
!@opts[:connec_preemption]
|
489
|
-
else
|
490
|
-
!is_connec_more_recent?(connec_entities.first, external_entities.first)
|
491
|
-
end
|
492
|
-
|
493
|
-
if keep_external
|
494
|
-
idmap.update(external_id: self.class.id_from_external_entity_hash(external_entities.first), name: self.class.object_name_from_external_entity_hash(external_entities.first))
|
495
|
-
return {connec_entities: [], external_entities: [{entity: map_to_connec(external_entities.first), idmap: idmap}]}
|
496
|
-
else
|
497
|
-
unfold_hash = Maestrano::Connector::Rails::ConnecHelper.unfold_references(connec_entities.first, self.class.references, @organization)
|
498
|
-
entity = unfold_hash[:entity]
|
499
|
-
idmap.update(name: self.class.object_name_from_connec_entity_hash(entity), connec_id: unfold_hash[:connec_id])
|
500
|
-
idmap.update(external_id: self.class.id_from_external_entity_hash(external_entities.first)) unless external_entities.empty?
|
501
|
-
return {connec_entities: [{entity: map_to_external(entity), idmap: idmap, id_refs_only_connec_entity: {}}], external_entities: []}
|
502
|
-
end
|
433
|
+
Maestrano::Connector::Rails::Services::DataConsolidator.new(@organization, self, @opts).consolidate_singleton(connec_entities, external_entities)
|
503
434
|
end
|
504
435
|
|
505
436
|
# ----------------------------------------------
|
@@ -548,59 +479,6 @@ module Maestrano::Connector::Rails::Concerns::Entity
|
|
548
479
|
end
|
549
480
|
end
|
550
481
|
|
551
|
-
def not_modified_since_last_push_to_connec?(idmap, entity)
|
552
|
-
not_modified = idmap.last_push_to_connec && idmap.last_push_to_connec > self.class.last_update_date_from_external_entity_hash(entity)
|
553
|
-
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Discard #{Maestrano::Connector::Rails::External.external_name} #{self.class.external_entity_name} : #{entity}") if not_modified
|
554
|
-
not_modified
|
555
|
-
end
|
556
|
-
|
557
|
-
def not_modified_since_last_push_to_external?(idmap, entity)
|
558
|
-
not_modified = idmap.last_push_to_external && idmap.last_push_to_external > entity['updated_at']
|
559
|
-
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Discard Connec! #{self.class.connec_entity_name} : #{entity}") if not_modified
|
560
|
-
not_modified
|
561
|
-
end
|
562
|
-
|
563
|
-
def before_date_filtering_limit?(entity, external = true)
|
564
|
-
@organization.date_filtering_limit && @organization.date_filtering_limit > (external ? self.class.creation_date_from_external_entity_hash(entity) : entity['created_at'])
|
565
|
-
end
|
566
|
-
|
567
|
-
def is_connec_more_recent?(connec_entity, external_entity)
|
568
|
-
connec_entity['updated_at'] > self.class.last_update_date_from_external_entity_hash(external_entity)
|
569
|
-
end
|
570
|
-
|
571
|
-
# This methods try to find a external entity among all the external entities matching the connec (mapped) one (same id)
|
572
|
-
# If it does not find any, there is no conflict, and it returns the mapped connec entity
|
573
|
-
# If it finds one, the conflict is solved either with options or using the entities timestamps
|
574
|
-
# If the connec entity is kept, it is returned mapped and the matching external entity is discarded (deleted from the array)
|
575
|
-
# Else the method returns nil, meaning the connec entity is discarded
|
576
|
-
def solve_conflict(connec_entity, external_entities, external_entity_name, idmap, id_refs_only_connec_entity)
|
577
|
-
# Here the connec_entity['id'] is an external id (String) because the entity has been unfolded.
|
578
|
-
external_entity = external_entities.find { |entity| connec_entity['id'] == self.class.id_from_external_entity_hash(entity) }
|
579
|
-
# No conflict
|
580
|
-
return map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity) unless external_entity
|
581
|
-
|
582
|
-
# Conflict
|
583
|
-
# We keep the most recently updated entity
|
584
|
-
keep_connec = @opts.key?(:connec_preemption) ? @opts[:connec_preemption] : is_connec_more_recent?(connec_entity, external_entity)
|
585
|
-
|
586
|
-
if keep_connec
|
587
|
-
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Conflict between #{Maestrano::Connector::Rails::External.external_name} #{external_entity_name} #{external_entity} and Connec! #{self.class.connec_entity_name} #{connec_entity}. Entity from Connec! kept")
|
588
|
-
external_entities.delete(external_entity)
|
589
|
-
map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
590
|
-
else
|
591
|
-
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Conflict between #{Maestrano::Connector::Rails::External.external_name} #{external_entity_name} #{external_entity} and Connec! #{self.class.connec_entity_name} #{connec_entity}. Entity from external kept")
|
592
|
-
nil
|
593
|
-
end
|
594
|
-
end
|
595
|
-
|
596
|
-
def map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
597
|
-
{entity: map_to_external(connec_entity, idmap.last_push_to_external.nil?), idmap: idmap, id_refs_only_connec_entity: id_refs_only_connec_entity}
|
598
|
-
end
|
599
|
-
|
600
|
-
def map_external_entity_with_idmap(external_entity, connec_entity_name, idmap)
|
601
|
-
{entity: map_to_connec(external_entity, idmap.last_push_to_connec.nil?), idmap: idmap}
|
602
|
-
end
|
603
|
-
|
604
482
|
def fetch_connec(uri)
|
605
483
|
Maestrano::Connector::Rails::ConnectorLogger.log('debug', @organization, "Fetching data from connec entity=#{self.class.connec_entity_name}, url=#{uri}")
|
606
484
|
response = @connec_client.get(uri)
|
@@ -60,14 +60,6 @@ module Maestrano::Connector::Rails::Concerns::SubEntityBase
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
64
|
-
{entity: map_to(external_entity_name, connec_entity, idmap.last_push_to_external.nil?), idmap: idmap, id_refs_only_connec_entity: id_refs_only_connec_entity}
|
65
|
-
end
|
66
|
-
|
67
|
-
def map_external_entity_with_idmap(external_entity, connec_entity_name, idmap)
|
68
|
-
{entity: map_to(connec_entity_name, external_entity, idmap.last_push_to_connec.nil?), idmap: idmap}
|
69
|
-
end
|
70
|
-
|
71
63
|
# Maps the entity received from external after a creation or an update and complete the received ids with the connec ones
|
72
64
|
def map_and_complete_hash_with_connec_ids(external_hash, external_entity_name, connec_hash)
|
73
65
|
return nil if connec_hash.empty?
|
@@ -134,11 +134,11 @@ module Maestrano::Connector::Rails
|
|
134
134
|
end
|
135
135
|
|
136
136
|
def push_to_connec_enabled?(entity)
|
137
|
-
synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_connec) && entity&.class
|
137
|
+
synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_connec) && entity&.class&.can_write_connec?
|
138
138
|
end
|
139
139
|
|
140
140
|
def push_to_external_enabled?(entity)
|
141
|
-
synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_external) && entity&.class
|
141
|
+
synchronized_entities.dig(EntityHelper.snake_name(entity), :can_push_to_external) && entity&.class&.can_write_external?
|
142
142
|
end
|
143
143
|
|
144
144
|
def set_instance_metadata
|
@@ -0,0 +1,157 @@
|
|
1
|
+
module Maestrano::Connector::Rails::Services
|
2
|
+
class DataConsolidator
|
3
|
+
def initialize(organization, entity_self, options)
|
4
|
+
@is_a_subentity = entity_self.is_a?(Maestrano::Connector::Rails::Concerns::SubEntityBase)
|
5
|
+
@organization = organization
|
6
|
+
@current_entity = entity_self
|
7
|
+
@opts = options
|
8
|
+
end
|
9
|
+
|
10
|
+
def consolidate_singleton(connec_entities, external_entities)
|
11
|
+
return {connec_entities: [], external_entities: []} if external_entities.empty? && connec_entities.empty?
|
12
|
+
|
13
|
+
idmap = @current_entity.class.find_or_create_idmap(organization_id: @organization.id)
|
14
|
+
# No to_connec, to_external and inactive consideration here as we don't expect those workflow for singleton
|
15
|
+
|
16
|
+
external_id = @current_entity.class.id_from_external_entity_hash(external_entities.first) if external_entities.first
|
17
|
+
# A singleton will be either valid (updated/created) in the external app or in Connec!
|
18
|
+
# if keep_external is true we are keeping the external entity
|
19
|
+
keep_external = if external_entities.empty?
|
20
|
+
false
|
21
|
+
elsif connec_entities.empty?
|
22
|
+
true
|
23
|
+
elsif @opts.key?(:connec_preemption)
|
24
|
+
!@opts[:connec_preemption]
|
25
|
+
else
|
26
|
+
!connec_more_recent?(connec_entities.first, external_entities.first)
|
27
|
+
end
|
28
|
+
|
29
|
+
if keep_external
|
30
|
+
idmap.update(external_id: external_id, name: @current_entity.class.object_name_from_external_entity_hash(external_entities.first))
|
31
|
+
return {connec_entities: [], external_entities: [{entity: @current_entity.map_to_connec(external_entities.first), idmap: idmap}]}
|
32
|
+
else
|
33
|
+
unfold_hash = Maestrano::Connector::Rails::ConnecHelper.unfold_references(connec_entities.first, @current_entity.class.references, @organization)
|
34
|
+
entity = unfold_hash[:entity]
|
35
|
+
idmap.update(name: @current_entity.class.object_name_from_connec_entity_hash(entity), connec_id: unfold_hash[:connec_id])
|
36
|
+
idmap.update(external_id: @current_entity.class.id_from_external_entity_hash(external_entities.first)) unless external_entities.empty?
|
37
|
+
return {connec_entities: [{entity: @current_entity.map_to_external(entity), idmap: idmap, id_refs_only_connec_entity: {}}], external_entities: []}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def consolidate_connec_entities(connec_entities, external_entities, references, external_entity_name)
|
42
|
+
connec_entities.map do |entity|
|
43
|
+
# Entity has been created before date filtering limit
|
44
|
+
next if before_date_filtering_limit?(entity, false) && !@opts[:full_sync]
|
45
|
+
|
46
|
+
# Unfold the id arrays
|
47
|
+
# From that point on, the connec_entity contains only string of external ids
|
48
|
+
unfold_hash = Maestrano::Connector::Rails::ConnecHelper.unfold_references(entity, references, @organization)
|
49
|
+
entity = unfold_hash[:entity]
|
50
|
+
next unless entity # discard if at least one record reference is missing
|
51
|
+
connec_id = unfold_hash[:connec_id]
|
52
|
+
id_refs_only_connec_entity = unfold_hash[:id_refs_only_connec_entity]
|
53
|
+
|
54
|
+
if entity['id'].blank?
|
55
|
+
# Expecting find_or_create to be mostly a create
|
56
|
+
idmap = @current_entity.class.find_or_create_idmap(organization_id: @organization.id, name: @current_entity.class.object_name_from_connec_entity_hash(entity), external_entity: external_entity_name.downcase, connec_id: connec_id)
|
57
|
+
next map_connec_entity_with_idmap(entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
58
|
+
end
|
59
|
+
|
60
|
+
# Expecting find_or_create to be mostly a find
|
61
|
+
idmap = @current_entity.class.find_or_create_idmap(external_id: entity['id'], organization_id: @organization.id, external_entity: external_entity_name.downcase, connec_id: connec_id)
|
62
|
+
idmap.update(name: @current_entity.class.object_name_from_connec_entity_hash(entity))
|
63
|
+
|
64
|
+
next if idmap.external_inactive || !idmap.to_external || (!@opts[:full_sync] && not_modified_since_last_push_to_external?(idmap, entity))
|
65
|
+
|
66
|
+
# Check for conflict with entities from external
|
67
|
+
solve_conflict(entity, external_entities, external_entity_name, idmap, id_refs_only_connec_entity)
|
68
|
+
end.compact
|
69
|
+
end
|
70
|
+
|
71
|
+
def consolidate_external_entities(external_entities, connec_entity_name)
|
72
|
+
external_entities.map do |entity|
|
73
|
+
# Entity has been created before date filtering limit
|
74
|
+
next if before_date_filtering_limit?(entity) && !@opts[:full_sync]
|
75
|
+
|
76
|
+
entity_id = @current_entity.class.id_from_external_entity_hash(entity)
|
77
|
+
idmap = @current_entity.class.find_or_create_idmap(external_id: entity_id, organization_id: @organization.id, connec_entity: connec_entity_name.downcase)
|
78
|
+
|
79
|
+
# Not pushing entity to Connec!
|
80
|
+
next unless idmap.to_connec
|
81
|
+
|
82
|
+
# Not pushing to Connec! and flagging as inactive if inactive in external application
|
83
|
+
inactive = @current_entity.class.inactive_from_external_entity_hash?(entity)
|
84
|
+
idmap.update(external_inactive: inactive, name: @current_entity.class.object_name_from_external_entity_hash(entity))
|
85
|
+
next if inactive
|
86
|
+
|
87
|
+
# Entity has not been modified since its last push to connec!
|
88
|
+
next if !@opts[:full_sync] && not_modified_since_last_push_to_connec?(idmap, entity)
|
89
|
+
|
90
|
+
map_external_entity_with_idmap(entity, connec_entity_name, idmap)
|
91
|
+
end.compact
|
92
|
+
end
|
93
|
+
|
94
|
+
def before_date_filtering_limit?(entity, external = true)
|
95
|
+
@organization.date_filtering_limit && @organization.date_filtering_limit > (external ? @current_entity.class.creation_date_from_external_entity_hash(entity) : entity['created_at'])
|
96
|
+
end
|
97
|
+
|
98
|
+
def not_modified_since_last_push_to_connec?(idmap, entity)
|
99
|
+
not_modified = idmap.last_push_to_connec && idmap.last_push_to_connec > @current_entity.class.last_update_date_from_external_entity_hash(entity)
|
100
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Discard #{Maestrano::Connector::Rails::External.external_name} #{@current_entity.class.external_entity_name} : #{entity}") if not_modified
|
101
|
+
not_modified
|
102
|
+
end
|
103
|
+
|
104
|
+
def not_modified_since_last_push_to_external?(idmap, entity)
|
105
|
+
not_modified = idmap.last_push_to_external && idmap.last_push_to_external > entity['updated_at']
|
106
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Discard Connec! #{@current_entity.class.connec_entity_name} : #{entity}") if not_modified
|
107
|
+
not_modified
|
108
|
+
end
|
109
|
+
|
110
|
+
def map_external_entity_with_idmap(external_entity, connec_entity_name, idmap)
|
111
|
+
entity = if @is_a_subentity
|
112
|
+
@current_entity.map_to(connec_entity_name, external_entity, idmap.last_push_to_connec.nil?)
|
113
|
+
else
|
114
|
+
@current_entity.map_to_connec(external_entity, idmap.last_push_to_connec.nil?)
|
115
|
+
end
|
116
|
+
{entity: entity, idmap: idmap}
|
117
|
+
end
|
118
|
+
|
119
|
+
def map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
120
|
+
entity = if @is_a_subentity
|
121
|
+
@current_entity.map_to(external_entity_name, connec_entity, idmap.last_push_to_external.nil?)
|
122
|
+
else
|
123
|
+
@current_entity.map_to_external(connec_entity, idmap.last_push_to_external.nil?)
|
124
|
+
end
|
125
|
+
{entity: entity, idmap: idmap, id_refs_only_connec_entity: id_refs_only_connec_entity}
|
126
|
+
end
|
127
|
+
|
128
|
+
# This methods try to find a external entity among all the external entities matching the connec (mapped) one (same id)
|
129
|
+
# If it does not find any, there is no conflict, and it returns the mapped connec entity
|
130
|
+
# If it finds one, the conflict is solved either with options or using the entities timestamps
|
131
|
+
# If the connec entity is kept, it is returned mapped and the matching external entity is discarded (deleted from the array)
|
132
|
+
# Else the method returns nil, meaning the connec entity is discarded
|
133
|
+
def solve_conflict(connec_entity, external_entities, external_entity_name, idmap, id_refs_only_connec_entity)
|
134
|
+
# Here the connec_entity['id'] is an external id (String) because the entity has been unfolded.
|
135
|
+
external_entity = external_entities.find { |entity| connec_entity['id'] == @current_entity.class.id_from_external_entity_hash(entity) }
|
136
|
+
# No conflict
|
137
|
+
return map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity) unless external_entity
|
138
|
+
|
139
|
+
# Conflict
|
140
|
+
# We keep the most recently updated entity
|
141
|
+
keep_connec = @opts.key?(:connec_preemption) ? @opts[:connec_preemption] : connec_more_recent?(connec_entity, external_entity)
|
142
|
+
|
143
|
+
if keep_connec
|
144
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Conflict between #{Maestrano::Connector::Rails::External.external_name} #{external_entity_name} #{external_entity} and Connec! #{@current_entity.class.connec_entity_name} #{connec_entity}. Entity from Connec! kept")
|
145
|
+
external_entities.delete(external_entity)
|
146
|
+
map_connec_entity_with_idmap(connec_entity, external_entity_name, idmap, id_refs_only_connec_entity)
|
147
|
+
else
|
148
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', @organization, "Conflict between #{Maestrano::Connector::Rails::External.external_name} #{external_entity_name} #{external_entity} and Connec! #{@current_entity.class.connec_entity_name} #{connec_entity}. Entity from external kept")
|
149
|
+
nil
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def connec_more_recent?(connec_entity, external_entity)
|
154
|
+
connec_entity['updated_at'] > @current_entity.class.last_update_date_from_external_entity_hash(external_entity)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
@@ -2,19 +2,18 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
-
# stub: maestrano-connector-rails 2.0.2.pre.
|
5
|
+
# stub: maestrano-connector-rails 2.0.2.pre.RC6 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "maestrano-connector-rails".freeze
|
9
|
-
s.version = "2.0.2.pre.
|
9
|
+
s.version = "2.0.2.pre.RC6"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new("> 1.3.1".freeze) if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib".freeze]
|
13
13
|
s.authors = ["Maestrano".freeze]
|
14
|
-
s.date = "2017-02-
|
14
|
+
s.date = "2017-02-16"
|
15
15
|
s.description = "Maestrano is the next generation marketplace for SME applications. See https://sme.maestrano.com for details.".freeze
|
16
16
|
s.email = "developers@maestrano.com".freeze
|
17
|
-
s.executables = ["rails".freeze, "rake".freeze]
|
18
17
|
s.extra_rdoc_files = [
|
19
18
|
"LICENSE",
|
20
19
|
"README.md"
|
@@ -64,12 +63,11 @@ Gem::Specification.new do |s|
|
|
64
63
|
"app/models/maestrano/connector/rails/external.rb",
|
65
64
|
"app/models/maestrano/connector/rails/id_map.rb",
|
66
65
|
"app/models/maestrano/connector/rails/organization.rb",
|
66
|
+
"app/models/maestrano/connector/rails/services/data_consolidator.rb",
|
67
67
|
"app/models/maestrano/connector/rails/sub_entity_base.rb",
|
68
68
|
"app/models/maestrano/connector/rails/synchronization.rb",
|
69
69
|
"app/models/maestrano/connector/rails/user.rb",
|
70
70
|
"app/models/maestrano/connector/rails/user_organization_rel.rb",
|
71
|
-
"bin/rails",
|
72
|
-
"bin/rake",
|
73
71
|
"config/routes.rb",
|
74
72
|
"db/migrate/20151122162100_create_users.rb",
|
75
73
|
"db/migrate/20151122162414_create_organizations.rb",
|
@@ -229,7 +227,7 @@ Gem::Specification.new do |s|
|
|
229
227
|
|
230
228
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
231
229
|
s.add_runtime_dependency(%q<rails>.freeze, ["~> 4.2"])
|
232
|
-
s.add_runtime_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.
|
230
|
+
s.add_runtime_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.3"])
|
233
231
|
s.add_runtime_dependency(%q<attr_encrypted>.freeze, ["~> 1.4.0"])
|
234
232
|
s.add_runtime_dependency(%q<autoprefixer-rails>.freeze, [">= 0"])
|
235
233
|
s.add_runtime_dependency(%q<bootstrap-sass>.freeze, [">= 0"])
|
@@ -242,7 +240,6 @@ Gem::Specification.new do |s|
|
|
242
240
|
s.add_runtime_dependency(%q<sidekiq-unique-jobs>.freeze, [">= 0"])
|
243
241
|
s.add_runtime_dependency(%q<sinatra>.freeze, [">= 0"])
|
244
242
|
s.add_runtime_dependency(%q<slim>.freeze, [">= 0"])
|
245
|
-
s.add_development_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
246
243
|
s.add_development_dependency(%q<activerecord-jdbcsqlite3-adapter>.freeze, [">= 0"])
|
247
244
|
s.add_development_dependency(%q<bundler>.freeze, [">= 0"])
|
248
245
|
s.add_development_dependency(%q<factory_girl_rails>.freeze, [">= 0"])
|
@@ -256,9 +253,10 @@ Gem::Specification.new do |s|
|
|
256
253
|
s.add_development_dependency(%q<simplecov>.freeze, [">= 0"])
|
257
254
|
s.add_development_dependency(%q<sqlite3>.freeze, [">= 0"])
|
258
255
|
s.add_development_dependency(%q<timecop>.freeze, [">= 0"])
|
256
|
+
s.add_development_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
259
257
|
else
|
260
258
|
s.add_dependency(%q<rails>.freeze, ["~> 4.2"])
|
261
|
-
s.add_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.
|
259
|
+
s.add_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.3"])
|
262
260
|
s.add_dependency(%q<attr_encrypted>.freeze, ["~> 1.4.0"])
|
263
261
|
s.add_dependency(%q<autoprefixer-rails>.freeze, [">= 0"])
|
264
262
|
s.add_dependency(%q<bootstrap-sass>.freeze, [">= 0"])
|
@@ -271,7 +269,6 @@ Gem::Specification.new do |s|
|
|
271
269
|
s.add_dependency(%q<sidekiq-unique-jobs>.freeze, [">= 0"])
|
272
270
|
s.add_dependency(%q<sinatra>.freeze, [">= 0"])
|
273
271
|
s.add_dependency(%q<slim>.freeze, [">= 0"])
|
274
|
-
s.add_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
275
272
|
s.add_dependency(%q<activerecord-jdbcsqlite3-adapter>.freeze, [">= 0"])
|
276
273
|
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
277
274
|
s.add_dependency(%q<factory_girl_rails>.freeze, [">= 0"])
|
@@ -285,10 +282,11 @@ Gem::Specification.new do |s|
|
|
285
282
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
286
283
|
s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
|
287
284
|
s.add_dependency(%q<timecop>.freeze, [">= 0"])
|
285
|
+
s.add_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
288
286
|
end
|
289
287
|
else
|
290
288
|
s.add_dependency(%q<rails>.freeze, ["~> 4.2"])
|
291
|
-
s.add_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.
|
289
|
+
s.add_dependency(%q<maestrano-rails>.freeze, ["~> 1.0.3"])
|
292
290
|
s.add_dependency(%q<attr_encrypted>.freeze, ["~> 1.4.0"])
|
293
291
|
s.add_dependency(%q<autoprefixer-rails>.freeze, [">= 0"])
|
294
292
|
s.add_dependency(%q<bootstrap-sass>.freeze, [">= 0"])
|
@@ -301,7 +299,6 @@ Gem::Specification.new do |s|
|
|
301
299
|
s.add_dependency(%q<sidekiq-unique-jobs>.freeze, [">= 0"])
|
302
300
|
s.add_dependency(%q<sinatra>.freeze, [">= 0"])
|
303
301
|
s.add_dependency(%q<slim>.freeze, [">= 0"])
|
304
|
-
s.add_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
305
302
|
s.add_dependency(%q<activerecord-jdbcsqlite3-adapter>.freeze, [">= 0"])
|
306
303
|
s.add_dependency(%q<bundler>.freeze, [">= 0"])
|
307
304
|
s.add_dependency(%q<factory_girl_rails>.freeze, [">= 0"])
|
@@ -315,6 +312,7 @@ Gem::Specification.new do |s|
|
|
315
312
|
s.add_dependency(%q<simplecov>.freeze, [">= 0"])
|
316
313
|
s.add_dependency(%q<sqlite3>.freeze, [">= 0"])
|
317
314
|
s.add_dependency(%q<timecop>.freeze, [">= 0"])
|
315
|
+
s.add_dependency(%q<webmock>.freeze, ["~> 1.24.1"])
|
318
316
|
end
|
319
317
|
end
|
320
318
|
|
@@ -166,7 +166,7 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
166
166
|
let(:external_name) { 'sc_e1' }
|
167
167
|
let(:connec_name) { 'connec1' }
|
168
168
|
let(:modelled_external_entities) { {external_name => {connec_name => [entity]}} }
|
169
|
-
before
|
169
|
+
before do
|
170
170
|
allow(subject.class).to receive(:connec_entities_names).and_return(['connec1'])
|
171
171
|
allow(subject.class).to receive(:external_entities_names).and_return(['sc_e1'])
|
172
172
|
allow(Entities::SubEntities::ScE1).to receive(:external?).and_return(true)
|
@@ -175,7 +175,7 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
175
175
|
allow(Entities::SubEntities::ScE1).to receive(:object_name_from_external_entity_hash).and_return(human_name)
|
176
176
|
allow(Entities::SubEntities::ScE1).to receive(:last_update_date_from_external_entity_hash).and_return(date)
|
177
177
|
allow_any_instance_of(Entities::SubEntities::ScE1).to receive(:map_to).and_return(mapped_entity)
|
178
|
-
|
178
|
+
end
|
179
179
|
|
180
180
|
context 'when idmap exists' do
|
181
181
|
let!(:idmap) { create(:idmap, organization: organization, connec_entity: connec_name.downcase, external_entity: external_name.downcase, external_id: id) }
|
@@ -199,9 +199,7 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
199
199
|
end
|
200
200
|
|
201
201
|
context 'when entity is inactive' do
|
202
|
-
before {
|
203
|
-
allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)
|
204
|
-
}
|
202
|
+
before { allow(Entities::SubEntities::ScE1).to receive(:inactive_from_external_entity_hash?).and_return(true)}
|
205
203
|
|
206
204
|
it 'discards the entity' do
|
207
205
|
expect(subject.consolidate_and_map_external_entities(modelled_external_entities)).to eql({external_name => {connec_name => []}})
|
data/spec/spec_helper.rb
CHANGED
@@ -27,7 +27,7 @@ RSpec.configure do |config|
|
|
27
27
|
allow(Maestrano::Connector::Rails::External).to receive(:external_name).and_return('External app')
|
28
28
|
allow(Maestrano::Connector::Rails::External).to receive(:get_client).and_return(Object.new)
|
29
29
|
allow(Maestrano::Connector::Rails::External).to receive(:entities_list).and_return(%w(entity1 entity2))
|
30
|
-
stub_request(:get,
|
30
|
+
stub_request(:get, %r(#{Maestrano['default'].param('api.host')}/api/v1/account/groups/[\w-]*)).
|
31
31
|
to_return({status: 200, body: "{}", headers: {}})
|
32
32
|
Rails.cache.clear
|
33
33
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: maestrano-connector-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.2.pre.
|
4
|
+
version: 2.0.2.pre.RC6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Maestrano
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-02-
|
11
|
+
date: 2017-02-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.0.
|
33
|
+
version: 1.0.3
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.0.
|
40
|
+
version: 1.0.3
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: attr_encrypted
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -206,20 +206,6 @@ dependencies:
|
|
206
206
|
- - ">="
|
207
207
|
- !ruby/object:Gem::Version
|
208
208
|
version: '0'
|
209
|
-
- !ruby/object:Gem::Dependency
|
210
|
-
name: webmock
|
211
|
-
requirement: !ruby/object:Gem::Requirement
|
212
|
-
requirements:
|
213
|
-
- - "~>"
|
214
|
-
- !ruby/object:Gem::Version
|
215
|
-
version: 1.24.1
|
216
|
-
type: :development
|
217
|
-
prerelease: false
|
218
|
-
version_requirements: !ruby/object:Gem::Requirement
|
219
|
-
requirements:
|
220
|
-
- - "~>"
|
221
|
-
- !ruby/object:Gem::Version
|
222
|
-
version: 1.24.1
|
223
209
|
- !ruby/object:Gem::Dependency
|
224
210
|
name: activerecord-jdbcsqlite3-adapter
|
225
211
|
requirement: !ruby/object:Gem::Requirement
|
@@ -402,12 +388,24 @@ dependencies:
|
|
402
388
|
- - ">="
|
403
389
|
- !ruby/object:Gem::Version
|
404
390
|
version: '0'
|
391
|
+
- !ruby/object:Gem::Dependency
|
392
|
+
name: webmock
|
393
|
+
requirement: !ruby/object:Gem::Requirement
|
394
|
+
requirements:
|
395
|
+
- - "~>"
|
396
|
+
- !ruby/object:Gem::Version
|
397
|
+
version: 1.24.1
|
398
|
+
type: :development
|
399
|
+
prerelease: false
|
400
|
+
version_requirements: !ruby/object:Gem::Requirement
|
401
|
+
requirements:
|
402
|
+
- - "~>"
|
403
|
+
- !ruby/object:Gem::Version
|
404
|
+
version: 1.24.1
|
405
405
|
description: Maestrano is the next generation marketplace for SME applications. See
|
406
406
|
https://sme.maestrano.com for details.
|
407
407
|
email: developers@maestrano.com
|
408
|
-
executables:
|
409
|
-
- rails
|
410
|
-
- rake
|
408
|
+
executables: []
|
411
409
|
extensions: []
|
412
410
|
extra_rdoc_files:
|
413
411
|
- LICENSE
|
@@ -457,12 +455,11 @@ files:
|
|
457
455
|
- app/models/maestrano/connector/rails/external.rb
|
458
456
|
- app/models/maestrano/connector/rails/id_map.rb
|
459
457
|
- app/models/maestrano/connector/rails/organization.rb
|
458
|
+
- app/models/maestrano/connector/rails/services/data_consolidator.rb
|
460
459
|
- app/models/maestrano/connector/rails/sub_entity_base.rb
|
461
460
|
- app/models/maestrano/connector/rails/synchronization.rb
|
462
461
|
- app/models/maestrano/connector/rails/user.rb
|
463
462
|
- app/models/maestrano/connector/rails/user_organization_rel.rb
|
464
|
-
- bin/rails
|
465
|
-
- bin/rake
|
466
463
|
- config/routes.rb
|
467
464
|
- db/migrate/20151122162100_create_users.rb
|
468
465
|
- db/migrate/20151122162414_create_organizations.rb
|
data/bin/rails
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'rails' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("railties", "rails")
|
data/bin/rake
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
# frozen_string_literal: true
|
3
|
-
#
|
4
|
-
# This file was generated by Bundler.
|
5
|
-
#
|
6
|
-
# The application 'rake' is installed as part of a gem, and
|
7
|
-
# this file is here to facilitate running it.
|
8
|
-
#
|
9
|
-
|
10
|
-
require "pathname"
|
11
|
-
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
12
|
-
Pathname.new(__FILE__).realpath)
|
13
|
-
|
14
|
-
require "rubygems"
|
15
|
-
require "bundler/setup"
|
16
|
-
|
17
|
-
load Gem.bin_path("rake", "rake")
|