maestrano-connector-rails 0.3.13 → 0.4.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/VERSION +1 -1
- data/app/jobs/maestrano/connector/rails/synchronization_job.rb +10 -4
- data/app/models/maestrano/connector/rails/concerns/entity.rb +43 -32
- data/app/models/maestrano/connector/rails/organization.rb +2 -2
- data/app/models/maestrano/connector/rails/synchronization.rb +9 -0
- data/lib/generators/connector/templates/oauth_controller.rb +1 -0
- data/maestrano-connector-rails.gemspec +6 -4
- data/spec/jobs/synchronization_job_spec.rb +26 -0
- data/spec/models/complex_entity_spec.rb +3 -3
- data/spec/models/entity_spec.rb +99 -48
- data/spec/models/{organizaztion_spec.rb → organization_spec.rb} +2 -2
- data/spec/models/synchronization_spec.rb +22 -0
- data/template/maestrano-connector-template.rb +10 -0
- data/template/routes.rb +7 -0
- data/template/sidekiq.rb +1 -0
- data/template/sidekiq.yml +4 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 296c3f72e80c6876a39e3161e752292bad97d03f
|
4
|
+
data.tar.gz: 155def8dc10315c64595ae0c4e6284890f896254
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 97e21e2088c3d7774052fe11aa6380e456dfa884a1165a57696bc21b723db99696410cde4011d2c6f9824a92d0e15fa7251d2c21a48dd6892ec3ea0293264879
|
7
|
+
data.tar.gz: 9915cf3654bb531970ccaf5dee230a53ec5de525b96b08659bd2dd912d67eca7457619c8f5545c9695daa63b6d1594c2084f7d1d58e1995adb0d415f729b158d
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
@@ -11,12 +11,19 @@ module Maestrano::Connector::Rails
|
|
11
11
|
return unless organization.sync_enabled
|
12
12
|
|
13
13
|
# Check if previous synchronization is still running
|
14
|
-
|
15
|
-
|
16
|
-
ConnectorLogger.log('info', organization, "Previous synchronization is still running")
|
14
|
+
if Synchronization.where(organization_id: organization.id, status: 'RUNNING').where(created_at: (30.minutes.ago..Time.now)).exists?
|
15
|
+
ConnectorLogger.log('info', organization, "Synchronization skipped: Previous synchronization is still running")
|
17
16
|
return
|
18
17
|
end
|
19
18
|
|
19
|
+
# Check if recovery mode: last 3 synchronizations have failed
|
20
|
+
if Synchronization.where(organization_id: organization.id, status: 'ERROR').order(created_at: :desc).limit(3).count == 3 \
|
21
|
+
&& Synchronization.where(organization_id: organization.id).order(created_at: :desc).limit(1).first.updated_at > 1.day.ago
|
22
|
+
ConnectorLogger.log('info', organization, "Synchronization skipped: Recovery mode (three previous synchronizations have failed)")
|
23
|
+
return
|
24
|
+
end
|
25
|
+
|
26
|
+
# Trigger synchronization
|
20
27
|
ConnectorLogger.log('info', organization, "Start synchronization, opts=#{opts}")
|
21
28
|
current_synchronization = Synchronization.create_running(organization)
|
22
29
|
|
@@ -49,7 +56,6 @@ module Maestrano::Connector::Rails
|
|
49
56
|
def sync_entity(entity_name, organization, connec_client, external_client, last_synchronization, opts)
|
50
57
|
entity_instance = "Entities::#{entity_name.titleize.split.join}".constantize.new
|
51
58
|
|
52
|
-
|
53
59
|
entity_instance.before_sync(connec_client, external_client, last_synchronization, organization, opts)
|
54
60
|
external_entities = entity_instance.get_external_entities(external_client, last_synchronization, organization, opts)
|
55
61
|
connec_entities = entity_instance.get_connec_entities(connec_client, last_synchronization, organization, opts)
|
@@ -117,11 +117,11 @@ module Maestrano::Connector::Rails::Concerns::Entity
|
|
117
117
|
end
|
118
118
|
|
119
119
|
def can_read_connec?
|
120
|
-
|
120
|
+
can_write_external?
|
121
121
|
end
|
122
122
|
|
123
123
|
def can_read_external?
|
124
|
-
|
124
|
+
can_write_connec?
|
125
125
|
end
|
126
126
|
|
127
127
|
def can_write_connec?
|
@@ -191,14 +191,14 @@ module Maestrano::Connector::Rails::Concerns::Entity
|
|
191
191
|
query_params[:$filter] = filter
|
192
192
|
end
|
193
193
|
response = client.get("/#{self.class.normalized_connec_entity_name}?#{query_params.to_query}")
|
194
|
-
raise "No data received from Connec! when trying to fetch #{self.class.
|
194
|
+
raise "No data received from Connec! when trying to fetch #{self.class.normalized_connec_entity_name}" unless response
|
195
195
|
|
196
196
|
response_hash = JSON.parse(response.body)
|
197
197
|
Maestrano::Connector::Rails::ConnectorLogger.log('debug', organization, "received first page entity=#{self.class.connec_entity_name}, response=#{response.body}")
|
198
198
|
if response_hash["#{self.class.normalized_connec_entity_name}"]
|
199
199
|
entities << response_hash["#{self.class.normalized_connec_entity_name}"]
|
200
200
|
else
|
201
|
-
raise "Received unrecognized Connec! data when trying to fetch #{self.class.
|
201
|
+
raise "Received unrecognized Connec! data when trying to fetch #{self.class.normalized_connec_entity_name}"
|
202
202
|
end
|
203
203
|
|
204
204
|
# Fetch subsequent pages
|
@@ -231,42 +231,53 @@ module Maestrano::Connector::Rails::Concerns::Entity
|
|
231
231
|
return unless self.class.can_write_connec?
|
232
232
|
|
233
233
|
Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending #{Maestrano::Connector::Rails::External.external_name} #{self.class.external_entity_name.pluralize} to Connec! #{connec_entity_name.pluralize}")
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
234
|
+
|
235
|
+
request_per_call = 100
|
236
|
+
start = 0
|
237
|
+
while start < mapped_external_entities_with_idmaps.size
|
238
|
+
# Prepare batch request
|
239
|
+
batch_entities = mapped_external_entities_with_idmaps.slice(start, request_per_call)
|
240
|
+
batch_request = {sequential: true, ops: []}
|
241
|
+
batch_entities.each do |mapped_external_entity_with_idmap|
|
242
|
+
external_entity = mapped_external_entity_with_idmap[:entity]
|
243
|
+
idmap = mapped_external_entity_with_idmap[:idmap]
|
239
244
|
if idmap.connec_id.blank?
|
240
|
-
|
241
|
-
idmap.update_attributes(connec_id: connec_entity['id'], last_push_to_connec: Time.now, message: nil)
|
245
|
+
batch_request[:ops] << batch_op('post', external_entity, nil, self.class.normalize_connec_entity_name(connec_entity_name), organization)
|
242
246
|
else
|
243
247
|
next unless self.class.can_update_connec?
|
244
|
-
|
245
|
-
idmap.update_attributes(last_push_to_connec: Time.now, message: nil)
|
248
|
+
batch_request[:ops] << batch_op('put', external_entity, idmap.connec_id, self.class.normalize_connec_entity_name(connec_entity_name), organization)
|
246
249
|
end
|
247
|
-
rescue => e
|
248
|
-
# Store Connec! error if any
|
249
|
-
Maestrano::Connector::Rails::ConnectorLogger.log('error', organization, "Error while pushing to Connec!: #{e}")
|
250
|
-
idmap.update_attributes(message: e.message)
|
251
250
|
end
|
252
|
-
end
|
253
|
-
end
|
254
251
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
252
|
+
# Batch call
|
253
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending batch request to Connec! for #{self.class.normalize_connec_entity_name(connec_entity_name)}. Batch_request_size: #{batch_request[:ops].size}. Call_number: #{(start/request_per_call) + 1}")
|
254
|
+
response = connec_client.post('/batch', batch_request)
|
255
|
+
response = JSON.parse(response.body)
|
256
|
+
|
257
|
+
# Parse barch response
|
258
|
+
response['results'].each_with_index do |result, index|
|
259
|
+
if result['status'] == 200
|
260
|
+
batch_entities[index][:idmap].update_attributes(last_push_to_connec: Time.now, message: nil)
|
261
|
+
elsif result['status'] == 201
|
262
|
+
batch_entities[index][:idmap].update_attributes(connec_id: result['body'][self.class.normalize_connec_entity_name(connec_entity_name)]['id'], last_push_to_connec: Time.now, message: nil)
|
263
|
+
else
|
264
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('error', organization, "Error while pushing to Connec!: #{result['body']}")
|
265
|
+
batch_entities[index][:idmap].update_attributes(message: result['body'])
|
266
|
+
end
|
267
|
+
end
|
268
|
+
start += request_per_call
|
269
|
+
end
|
261
270
|
end
|
262
271
|
|
263
|
-
def
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
272
|
+
def batch_op(method, mapped_external_entity, id, connec_entity_name, organization)
|
273
|
+
Maestrano::Connector::Rails::ConnectorLogger.log('info', organization, "Sending #{method.upcase} #{connec_entity_name}: #{mapped_external_entity} to Connec! (Preparing batch request)")
|
274
|
+
{
|
275
|
+
method: method,
|
276
|
+
url: "/api/v2/#{organization.uid}/#{connec_entity_name}" + (id.nil? ? '' : "/#{id}"),
|
277
|
+
params: {
|
278
|
+
"#{connec_entity_name}".to_sym => mapped_external_entity
|
279
|
+
}
|
280
|
+
}
|
270
281
|
end
|
271
282
|
|
272
283
|
def map_to_external_with_idmap(entity, organization)
|
@@ -23,8 +23,8 @@ module Maestrano::Connector::Rails
|
|
23
23
|
#===================================
|
24
24
|
has_many :user_organization_rels
|
25
25
|
has_many :users, through: :user_organization_rels
|
26
|
-
has_many :id_maps
|
27
|
-
has_many :synchronizations
|
26
|
+
has_many :id_maps, dependent: :destroy
|
27
|
+
has_many :synchronizations, dependent: :destroy
|
28
28
|
|
29
29
|
#===================================
|
30
30
|
# Validation
|
@@ -1,5 +1,7 @@
|
|
1
1
|
module Maestrano::Connector::Rails
|
2
2
|
class Synchronization < ActiveRecord::Base
|
3
|
+
# Keeping only 100 synchronizations per organization
|
4
|
+
after_create :clean_synchronizations
|
3
5
|
|
4
6
|
#===================================
|
5
7
|
# Associations
|
@@ -35,5 +37,12 @@ module Maestrano::Connector::Rails
|
|
35
37
|
def set_partial
|
36
38
|
self.update_attributes(partial: true)
|
37
39
|
end
|
40
|
+
|
41
|
+
def clean_synchronizations
|
42
|
+
count = self.organization.synchronizations.count
|
43
|
+
if count > 100
|
44
|
+
self.organization.synchronizations.limit(count - 100).destroy_all
|
45
|
+
end
|
46
|
+
end
|
38
47
|
end
|
39
48
|
end
|
@@ -2,16 +2,16 @@
|
|
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 0.
|
5
|
+
# stub: maestrano-connector-rails 0.4.0 ruby lib
|
6
6
|
|
7
7
|
Gem::Specification.new do |s|
|
8
8
|
s.name = "maestrano-connector-rails"
|
9
|
-
s.version = "0.
|
9
|
+
s.version = "0.4.0"
|
10
10
|
|
11
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
12
|
s.require_paths = ["lib"]
|
13
13
|
s.authors = ["Pierre Berard"]
|
14
|
-
s.date = "2016-04-
|
14
|
+
s.date = "2016-04-14"
|
15
15
|
s.description = "Maestrano is the next generation marketplace for SME applications. See https://maestrano.com for details."
|
16
16
|
s.email = "pierre.berard@maestrano.com"
|
17
17
|
s.executables = ["rails"]
|
@@ -162,7 +162,7 @@ Gem::Specification.new do |s|
|
|
162
162
|
"spec/models/entity_spec.rb",
|
163
163
|
"spec/models/external_spec.rb",
|
164
164
|
"spec/models/id_map_spec.rb",
|
165
|
-
"spec/models/
|
165
|
+
"spec/models/organization_spec.rb",
|
166
166
|
"spec/models/sub_entity_base_spec.rb",
|
167
167
|
"spec/models/synchronization_spec.rb",
|
168
168
|
"spec/models/user_organization_rel_spec.rb",
|
@@ -181,6 +181,8 @@ Gem::Specification.new do |s|
|
|
181
181
|
"template/settings/settings.yml",
|
182
182
|
"template/settings/test.yml",
|
183
183
|
"template/settings/uat.yml",
|
184
|
+
"template/sidekiq.rb",
|
185
|
+
"template/sidekiq.yml",
|
184
186
|
"template/spec_helper.rb"
|
185
187
|
]
|
186
188
|
s.homepage = "http://github.com/maestrano/maestrano-connector-rails"
|
@@ -19,6 +19,32 @@ describe Maestrano::Connector::Rails::SynchronizationJob do
|
|
19
19
|
context 'with sync_enabled set to true' do
|
20
20
|
before {organization.update(sync_enabled: true)}
|
21
21
|
|
22
|
+
describe 'recovery mode' do
|
23
|
+
describe 'skipping' do
|
24
|
+
before {
|
25
|
+
3.times do
|
26
|
+
organization.synchronizations.create(status: 'ERROR')
|
27
|
+
end
|
28
|
+
}
|
29
|
+
|
30
|
+
it 'skipped the sync if 3 failed sync' do
|
31
|
+
expect{ subject }.to_not change{ Maestrano::Connector::Rails::Synchronization.count }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe 'not skipping' do
|
36
|
+
before {
|
37
|
+
3.times do
|
38
|
+
organization.synchronizations.create(status: 'ERROR', created_at: 2.day.ago, updated_at: 2.day.ago)
|
39
|
+
end
|
40
|
+
}
|
41
|
+
|
42
|
+
it 'does not skip the sync if 3 failed sync but last sync more than a day ago' do
|
43
|
+
expect{ subject }.to change{ Maestrano::Connector::Rails::Synchronization.count }.by(1)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
22
48
|
it 'creates a synchronization' do
|
23
49
|
expect{ subject }.to change{ Maestrano::Connector::Rails::Synchronization.count }.by(1)
|
24
50
|
end
|
@@ -141,13 +141,13 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
141
141
|
|
142
142
|
it 'calls external_model_to_connec_model' do
|
143
143
|
allow(subject).to receive(:connec_model_to_external_model).and_return({})
|
144
|
-
expect(subject).to receive(:external_model_to_connec_model).with({a: {}}).and_return({})
|
144
|
+
expect(subject).to receive(:external_model_to_connec_model).with({a: {}}, organization).and_return({})
|
145
145
|
subject.consolidate_and_map_data({}, {a: {}}, organization, opt)
|
146
146
|
end
|
147
147
|
|
148
148
|
it 'calls connec_model_to_external_model' do
|
149
149
|
allow(subject).to receive(:external_model_to_connec_model).and_return({})
|
150
|
-
expect(subject).to receive(:connec_model_to_external_model).with({a: {}}).and_return({})
|
150
|
+
expect(subject).to receive(:connec_model_to_external_model).with({a: {}}, organization).and_return({})
|
151
151
|
subject.consolidate_and_map_data({a: {}}, {}, organization, opt)
|
152
152
|
end
|
153
153
|
|
@@ -388,7 +388,7 @@ describe Maestrano::Connector::Rails::ComplexEntity do
|
|
388
388
|
allow(klass).to receive(:external?).and_return(true)
|
389
389
|
allow(klass).to receive(:entity_name).and_return('n')
|
390
390
|
end
|
391
|
-
allow(client).to receive(:
|
391
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: [{status: 200, body: {connec1s: {}}}]}.to_json, {}))
|
392
392
|
}
|
393
393
|
it 'is successful' do
|
394
394
|
subject.push_entities_to_connec(client, external_hash, organization)
|
data/spec/models/entity_spec.rb
CHANGED
@@ -281,7 +281,7 @@ describe Maestrano::Connector::Rails::Entity do
|
|
281
281
|
before {
|
282
282
|
allow(client).to receive(:get).and_return(nil)
|
283
283
|
}
|
284
|
-
it { expect{ subject.get_connec_entities(client, nil, organization) }.to raise_error("No data received from Connec! when trying to fetch #{connec_name.pluralize}") }
|
284
|
+
it { expect{ subject.get_connec_entities(client, nil, organization) }.to raise_error("No data received from Connec! when trying to fetch #{connec_name.pluralize.downcase}") }
|
285
285
|
end
|
286
286
|
end
|
287
287
|
|
@@ -294,7 +294,7 @@ describe Maestrano::Connector::Rails::Entity do
|
|
294
294
|
end
|
295
295
|
|
296
296
|
describe 'push_entities_to_connec_to' do
|
297
|
-
let(:organization) { create(:organization) }
|
297
|
+
let(:organization) { create(:organization, uid: 'cld-123') }
|
298
298
|
let(:idmap1) { create(:idmap, organization: organization) }
|
299
299
|
let(:idmap2) { create(:idmap, organization: organization, connec_id: nil, last_push_to_connec: nil) }
|
300
300
|
let(:entity1) { {name: 'John'} }
|
@@ -310,8 +310,7 @@ describe Maestrano::Connector::Rails::Entity do
|
|
310
310
|
}
|
311
311
|
|
312
312
|
it 'does nothing' do
|
313
|
-
expect(subject).to_not receive(:
|
314
|
-
expect(subject).to_not receive(:update_connec_entity)
|
313
|
+
expect(subject).to_not receive(:batch_op)
|
315
314
|
subject.push_entities_to_connec_to(client, entities_with_idmaps, connec_name, organization)
|
316
315
|
end
|
317
316
|
end
|
@@ -319,66 +318,118 @@ describe Maestrano::Connector::Rails::Entity do
|
|
319
318
|
context 'when create_only' do
|
320
319
|
before {
|
321
320
|
allow(subject.class).to receive(:can_update_connec?).and_return(false)
|
321
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: []}.to_json, {}))
|
322
322
|
}
|
323
|
-
|
324
|
-
|
325
|
-
expect(subject).
|
323
|
+
|
324
|
+
it 'creates batch op for create only' do
|
325
|
+
expect(subject).to receive(:batch_op).once.with('post', entity2, nil, connec_name.downcase.pluralize, organization)
|
326
|
+
expect(subject).to_not receive(:batch_op).with('put', any_args)
|
326
327
|
subject.push_entities_to_connec_to(client, entities_with_idmaps, connec_name, organization)
|
327
328
|
end
|
328
329
|
end
|
329
330
|
|
330
|
-
|
331
|
-
|
332
|
-
|
331
|
+
context 'without errors' do
|
332
|
+
let(:result200) { {status: 200, body: {connec_name.downcase.pluralize.to_sym => {}}} }
|
333
|
+
let(:result201) { {status: 201, body: {connec_name.downcase.pluralize.to_sym => {id: id}}} }
|
334
|
+
before {
|
335
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: [result200, result201]}.to_json, {}))
|
336
|
+
}
|
333
337
|
|
334
|
-
|
335
|
-
|
336
|
-
|
338
|
+
let(:batch_request) {
|
339
|
+
{
|
340
|
+
sequential: true,
|
341
|
+
ops: [
|
342
|
+
{
|
343
|
+
:method=>"put",
|
344
|
+
:url=>"/api/v2/cld-123/people/#{idmap1.connec_id}",
|
345
|
+
:params=>{:people=>{:name=>"John"}}
|
346
|
+
},
|
347
|
+
{
|
348
|
+
:method=>"post",
|
349
|
+
:url=>"/api/v2/cld-123/people",
|
350
|
+
:params=>{:people=>{:name=>"Jane"}}
|
351
|
+
}
|
352
|
+
]
|
353
|
+
}
|
354
|
+
}
|
337
355
|
|
338
|
-
|
356
|
+
it 'calls batch op' do
|
357
|
+
expect(subject).to receive(:batch_op).twice
|
358
|
+
subject.push_entities_to_connec_to(client, entities_with_idmaps, connec_name, organization)
|
359
|
+
end
|
339
360
|
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
expect(idmap2.last_push_to_connec).to_not be_nil
|
345
|
-
end
|
361
|
+
it 'creates a batch request' do
|
362
|
+
expect(client).to receive(:post).with('/batch', batch_request)
|
363
|
+
subject.push_entities_to_connec_to(client, entities_with_idmaps, connec_name, organization)
|
364
|
+
end
|
346
365
|
|
347
|
-
|
348
|
-
|
349
|
-
idmap1.reload
|
350
|
-
expect(idmap1.message).to_not be nil
|
351
|
-
end
|
352
|
-
end
|
366
|
+
it 'update the idmaps' do
|
367
|
+
old_push_date = idmap1.last_push_to_connec
|
353
368
|
|
354
|
-
|
355
|
-
let(:entity) { {name: 'John'} }
|
369
|
+
subject.push_entities_to_connec_to(client, entities_with_idmaps, connec_name, organization)
|
356
370
|
|
357
|
-
|
358
|
-
|
359
|
-
|
371
|
+
idmap1.reload
|
372
|
+
expect(idmap1.last_push_to_connec).to_not eql(old_push_date)
|
373
|
+
idmap2.reload
|
374
|
+
expect(idmap2.connec_id).to eql(id)
|
375
|
+
expect(idmap2.last_push_to_connec).to_not be_nil
|
376
|
+
end
|
360
377
|
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
end
|
378
|
+
describe 'batch batch calls' do
|
379
|
+
let(:entities) { [] }
|
380
|
+
let(:results) { [] }
|
365
381
|
|
366
|
-
|
367
|
-
|
382
|
+
context 'when 100 entities' do
|
383
|
+
before {
|
384
|
+
100.times do
|
385
|
+
entities << entity_with_idmap1
|
386
|
+
results << result200
|
387
|
+
end
|
388
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: results}.to_json, {}))
|
389
|
+
}
|
390
|
+
|
391
|
+
it 'does one call' do
|
392
|
+
expect(client).to receive(:post).once
|
393
|
+
subject.push_entities_to_connec_to(client, entities, connec_name, organization)
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
context 'when more than 100 entities' do
|
398
|
+
before {
|
399
|
+
100.times do
|
400
|
+
entities << entity_with_idmap1
|
401
|
+
results << result200
|
402
|
+
end
|
403
|
+
entities << entity_with_idmap2
|
404
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: results}.to_json, {}), ActionDispatch::Response.new(200, {}, {results: [result201]}.to_json, {}))
|
405
|
+
}
|
406
|
+
|
407
|
+
it 'does several call' do
|
408
|
+
expect(client).to receive(:post).twice
|
409
|
+
subject.push_entities_to_connec_to(client, entities, connec_name, organization)
|
410
|
+
end
|
411
|
+
|
412
|
+
it 'updates the idmap' do
|
413
|
+
subject.push_entities_to_connec_to(client, entities, connec_name, organization)
|
414
|
+
idmap2.reload
|
415
|
+
expect(idmap2.connec_id).to eql(id)
|
416
|
+
expect(idmap2.last_push_to_connec).to_not be_nil
|
417
|
+
end
|
418
|
+
end
|
419
|
+
end
|
368
420
|
end
|
369
|
-
end
|
370
421
|
|
371
|
-
|
372
|
-
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
allow(client).to receive(:put).and_return(ActionDispatch::Response.new(200, {}, {}.to_json, {}))
|
377
|
-
}
|
422
|
+
context 'with errors' do
|
423
|
+
let(:result400) { {status: 400, body: 'Not Found'} }
|
424
|
+
before {
|
425
|
+
allow(client).to receive(:post).and_return(ActionDispatch::Response.new(200, {}, {results: [result400, result400]}.to_json, {}))
|
426
|
+
}
|
378
427
|
|
379
|
-
|
380
|
-
|
381
|
-
|
428
|
+
it 'stores the errr in the idmap' do
|
429
|
+
subject.push_entities_to_connec_to(client, entities_with_idmaps, '', organization)
|
430
|
+
idmap2.reload
|
431
|
+
expect(idmap2.message).to eq result400[:body]
|
432
|
+
end
|
382
433
|
end
|
383
434
|
end
|
384
435
|
|
@@ -13,8 +13,8 @@ describe Maestrano::Connector::Rails::Organization do
|
|
13
13
|
#Associations
|
14
14
|
it { should have_many(:user_organization_rels) }
|
15
15
|
it { should have_many(:users) }
|
16
|
-
it { should have_many(:id_maps) }
|
17
|
-
it { should have_many(:synchronizations) }
|
16
|
+
it { should have_many(:id_maps).dependent(:destroy) }
|
17
|
+
it { should have_many(:synchronizations).dependent(:destroy) }
|
18
18
|
|
19
19
|
describe 'creation' do
|
20
20
|
subject { Maestrano::Connector::Rails::Organization.new }
|
@@ -71,5 +71,27 @@ describe Maestrano::Connector::Rails::Synchronization do
|
|
71
71
|
expect(sync.partial).to be(true)
|
72
72
|
end
|
73
73
|
end
|
74
|
+
|
75
|
+
describe 'clean_synchronizations' do
|
76
|
+
let!(:organization) { create(:organization) }
|
77
|
+
let!(:sync) { create(:synchronization, organization: organization) }
|
78
|
+
let!(:sync2) { create(:synchronization, organization: organization) }
|
79
|
+
|
80
|
+
context 'when less than 100 syncs' do
|
81
|
+
it 'does nothing' do
|
82
|
+
expect{ sync.clean_synchronizations }.to_not change{ organization.synchronizations.count }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context 'when more than 100 syncs' do
|
87
|
+
before {
|
88
|
+
allow_any_instance_of(ActiveRecord::Associations::CollectionProxy).to receive(:count).and_return(102)
|
89
|
+
}
|
90
|
+
|
91
|
+
it 'destroy the idmaps' do
|
92
|
+
expect{ sync.clean_synchronizations }.to change{ Maestrano::Connector::Rails::Synchronization.count }.by(-2)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
74
96
|
end
|
75
97
|
end
|
@@ -61,6 +61,12 @@ gem 'uglifier', '>= 1.3.0'
|
|
61
61
|
gem 'maestrano-connector-rails'
|
62
62
|
gem 'config'
|
63
63
|
|
64
|
+
# Background jobs
|
65
|
+
gem 'sinatra', :require => nil
|
66
|
+
gem 'sidekiq'
|
67
|
+
gem 'sidekiq-cron'
|
68
|
+
gem 'slim'
|
69
|
+
|
64
70
|
|
65
71
|
gem_group :test do
|
66
72
|
gem 'simplecov'
|
@@ -95,6 +101,10 @@ after_bundle do
|
|
95
101
|
run 'echo \'uat:
|
96
102
|
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>\' >> config/secrets.yml'
|
97
103
|
|
104
|
+
# Sidekiq
|
105
|
+
copy_file 'sidekiq.yml', 'config/sidekiq.yml'
|
106
|
+
copy_file 'sidekiq.rb', 'config/initializers/sidekiq.rb'
|
107
|
+
|
98
108
|
# Settings
|
99
109
|
run 'bundle exec rails g config:install'
|
100
110
|
remove_dir 'config/settings'
|
data/template/routes.rb
CHANGED
@@ -10,4 +10,11 @@ Rails.application.routes.draw do
|
|
10
10
|
|
11
11
|
get 'synchronizations/index' => 'synchronizations#index'
|
12
12
|
get 'shared_entities/index' => 'shared_entities#index'
|
13
|
+
|
14
|
+
# Sidekiq Admin
|
15
|
+
require 'sidekiq/web'
|
16
|
+
Sidekiq::Web.use Rack::Auth::Basic do |username, password|
|
17
|
+
username == ENV['SIDEKIQ_USERNAME'] && password == ENV['SIDEKIQ_PASSWORD']
|
18
|
+
end
|
19
|
+
mount Sidekiq::Web => '/sidekiq'
|
13
20
|
end
|
data/template/sidekiq.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
Sidekiq::Cron::Job.create(name: 'AllSynchronizationsJob runs every hour', cron: '0 * * * *', class: 'Maestrano::Connector::Rails::AllSynchronizationsJob')
|
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: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pierre Berard
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: maestrano-rails
|
@@ -372,7 +372,7 @@ files:
|
|
372
372
|
- spec/models/entity_spec.rb
|
373
373
|
- spec/models/external_spec.rb
|
374
374
|
- spec/models/id_map_spec.rb
|
375
|
-
- spec/models/
|
375
|
+
- spec/models/organization_spec.rb
|
376
376
|
- spec/models/sub_entity_base_spec.rb
|
377
377
|
- spec/models/synchronization_spec.rb
|
378
378
|
- spec/models/user_organization_rel_spec.rb
|
@@ -391,6 +391,8 @@ files:
|
|
391
391
|
- template/settings/settings.yml
|
392
392
|
- template/settings/test.yml
|
393
393
|
- template/settings/uat.yml
|
394
|
+
- template/sidekiq.rb
|
395
|
+
- template/sidekiq.yml
|
394
396
|
- template/spec_helper.rb
|
395
397
|
homepage: http://github.com/maestrano/maestrano-connector-rails
|
396
398
|
licenses:
|