zuora_connect 1.5.40 → 1.5.302
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/models/zuora_connect/app_instance_base.rb +65 -140
- data/config/initializers/redis.rb +2 -2
- data/lib/resque/dynamic_queues.rb +11 -22
- data/lib/zuora_connect/controllers/helpers.rb +4 -9
- data/lib/zuora_connect/exceptions.rb +0 -19
- data/lib/zuora_connect/railtie.rb +1 -1
- data/lib/zuora_connect/version.rb +2 -1
- metadata +30 -57
- data/db/migrate/20180301052853_add_catalog_attempted_at.rb +0 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 70d948ee67b1668d35ba394188ff631af51c7edd
|
4
|
+
data.tar.gz: 07b812c7be3cf5ca81ebd8f24589492f321294b2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 419ab8e60210fb1c908764da9d7f1ba8b6919326dee5af5e565f8c261e27c9608642ef7610a338d89860e566db977df34d248cd020fe2ab543646e86f417b5af
|
7
|
+
data.tar.gz: ccc1f977ff420fd837e41e57d8d84d21532d3a23742862a94bb39404c690e742d9ced481ed0f12009ce2df7cda17a3b013dc43dee38b195d5c856b70c82a40fe
|
@@ -4,13 +4,12 @@ module ZuoraConnect
|
|
4
4
|
after_initialize :init
|
5
5
|
self.table_name = "zuora_connect_app_instances"
|
6
6
|
attr_accessor :options, :mode, :logins, :task_data, :last_refresh, :username, :password, :s3_client, :api_version
|
7
|
-
|
7
|
+
|
8
8
|
REFRESH_TIMEOUT = 2.minute #Used to determine how long to wait on current refresh call before executing another
|
9
9
|
INSTANCE_REFRESH_WINDOW = 30.minutes #Used to set how how long till app starts attempting to refresh cached task connect data
|
10
10
|
INSTANCE_REDIS_CACHE_PERIOD = 60.minutes #Used to determine how long to cached task data will live for
|
11
11
|
API_LIMIT_TIMEOUT = 2.minutes #Used to set the default for expiring timeout when api rate limiting is in effect
|
12
|
-
|
13
|
-
|
12
|
+
|
14
13
|
def init
|
15
14
|
@options = Hash.new
|
16
15
|
@logins = Hash.new
|
@@ -18,26 +17,22 @@ module ZuoraConnect
|
|
18
17
|
self.attr_builder("timezone", ZuoraConnect.configuration.default_time_zone)
|
19
18
|
self.attr_builder("locale", ZuoraConnect.configuration.default_locale)
|
20
19
|
PaperTrail.whodunnit = "Backend" if defined?(PaperTrail)
|
21
|
-
|
22
|
-
raise "The instance refresh window cannot be greater than the instance cache period"
|
23
|
-
end
|
24
|
-
self.apartment_switch(nil, true)
|
25
|
-
end
|
26
|
-
|
27
|
-
def apartment_switch(method = nil, migrate = false)
|
28
|
-
begin
|
20
|
+
begin
|
29
21
|
Apartment::Tenant.switch!(self.id) if self.persisted?
|
30
22
|
rescue Apartment::TenantNotFound => ex
|
31
23
|
Apartment::Tenant.create(self.id.to_s)
|
32
24
|
retry
|
33
25
|
end
|
34
|
-
if
|
26
|
+
if(ActiveRecord::Migrator.needs_migration?)
|
35
27
|
Apartment::Migrator.migrate(self.id)
|
36
28
|
end
|
29
|
+
if INSTANCE_REFRESH_WINDOW > INSTANCE_REDIS_CACHE_PERIOD
|
30
|
+
raise "The instance refresh window cannot be greater than the instance cache period"
|
31
|
+
end
|
37
32
|
Thread.current[:appinstance] = self
|
38
33
|
end
|
39
34
|
|
40
|
-
def new_session(session: self.data_lookup, username: self.access_token, password: self.refresh_token
|
35
|
+
def new_session(session: self.data_lookup, username: self.access_token, password: self.refresh_token)
|
41
36
|
@api_version = "v2"
|
42
37
|
@username = username
|
43
38
|
@password = password
|
@@ -67,31 +62,27 @@ module ZuoraConnect
|
|
67
62
|
|
68
63
|
if session.empty?
|
69
64
|
Rails.logger.info("[#{self.id}] REFRESHING - Session Empty")
|
70
|
-
raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
|
71
65
|
self.refresh(session)
|
72
66
|
|
73
|
-
elsif (self.id != session["appInstance"].to_i)
|
67
|
+
elsif (self.id != session["appInstance"].to_i)
|
74
68
|
Rails.logger.info("[#{self.id}] REFRESHING - AppInstance ID(#{self.id}) does not match session id(#{session["appInstance"].to_i})")
|
75
|
-
raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
|
76
69
|
self.refresh(session)
|
77
70
|
|
78
71
|
elsif session["#{self.id}::task_data"].blank?
|
79
72
|
Rails.logger.info("[#{self.id}] REFRESHING - Task Data Blank")
|
80
|
-
raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
|
81
73
|
self.refresh(session)
|
82
74
|
|
83
75
|
elsif session["#{self.id}::last_refresh"].blank?
|
84
|
-
Rails.logger.info("[#{self.id}] REFRESHING - No Time on Cookie")
|
85
|
-
raise ZuoraConnect::Exceptions::HoldingPattern if holding_pattern && !self.mark_for_refresh
|
76
|
+
Rails.logger.info("[#{self.id}] REFRESHING - No Time on Cookie")
|
86
77
|
self.refresh(session)
|
87
78
|
|
88
|
-
#
|
89
|
-
elsif (session["#{self.id}::last_refresh"].to_i < INSTANCE_REFRESH_WINDOW.ago.to_i) && self.mark_for_refresh
|
79
|
+
elsif (session["#{self.id}::last_refresh"].to_i < INSTANCE_REFRESH_WINDOW.ago.to_i) && !self.marked_for_refresh?
|
90
80
|
Rails.logger.info("[#{self.id}] REFRESHING - Session Old by #{time_expire.abs} second")
|
81
|
+
self.mark_for_refresh #We will mark that we are refreshing the expired session. This will help prevent race condition between multiple requests
|
91
82
|
self.refresh(session)
|
92
83
|
else
|
93
84
|
if time_expire < 0
|
94
|
-
Rails.logger.info(["[#{self.id}] REBUILDING - Expired by #{time_expire} seconds", self.marked_for_refresh? ? " cache updating as of #{self.
|
85
|
+
Rails.logger.info(["[#{self.id}] REBUILDING - Expired by #{time_expire} seconds", self.marked_for_refresh? ? " cache updating as of #{self.refreshed_at} seconds ago" : nil].compact.join(','))
|
95
86
|
else
|
96
87
|
Rails.logger.info("[#{self.id}] REBUILDING - Expires in #{time_expire} seconds")
|
97
88
|
end
|
@@ -101,18 +92,11 @@ module ZuoraConnect
|
|
101
92
|
begin
|
102
93
|
I18n.locale = self.locale
|
103
94
|
rescue I18n::InvalidLocale => ex
|
104
|
-
Rails.logger.
|
95
|
+
Rails.logger.error("Invalid Locale: #{ex.message}")
|
105
96
|
end
|
106
97
|
Time.zone = self.timezone
|
98
|
+
Thread.current[:appinstance] = self
|
107
99
|
return self
|
108
|
-
rescue ZuoraConnect::Exceptions::HoldingPattern => ex
|
109
|
-
while self.marked_for_refresh?
|
110
|
-
Rails.logger.info("[#{self.id}] Holding - Expires in #{self.reset_mark_expires_at}")
|
111
|
-
sleep(5)
|
112
|
-
end
|
113
|
-
self.reload_attributes([:refresh_token, :oauth_expires_at, :access_token])
|
114
|
-
session = self.data_lookup(session: session)
|
115
|
-
retry
|
116
100
|
end
|
117
101
|
|
118
102
|
def refresh(session = nil)
|
@@ -122,71 +106,60 @@ module ZuoraConnect
|
|
122
106
|
response = HTTParty.get(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}.json",:body => {:access_token => self.access_token})
|
123
107
|
response_time = Time.now - start
|
124
108
|
|
125
|
-
Rails.logger.
|
109
|
+
Rails.logger.info("[#{self.id}] REFRESH TASK - Connect Task Info Request Time #{response_time.round(2).to_s}")
|
126
110
|
if response.code == 200
|
127
|
-
build_task(JSON.parse(response.body), session)
|
128
111
|
@last_refresh = Time.now.to_i
|
129
|
-
|
130
|
-
|
112
|
+
|
113
|
+
build_task(JSON.parse(response.body), session)
|
131
114
|
else
|
132
|
-
Rails.logger.fatal("[#{self.id}] REFRESH TASK - Failed Code #{response.code}")
|
133
115
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
|
134
116
|
end
|
135
|
-
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError
|
117
|
+
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError
|
136
118
|
if (refresh_count += 1) < 3
|
137
|
-
Rails.logger.info("[#{self.id}] REFRESH TASK - #{ex.class} Retrying(#{refresh_count})")
|
138
119
|
retry
|
139
120
|
else
|
140
|
-
Rails.logger.fatal("[#{self.id}] REFRESH TASK - #{ex.class} Failed #{refresh_count}x")
|
141
121
|
raise
|
142
122
|
end
|
143
123
|
rescue ZuoraConnect::Exceptions::ConnectCommunicationError => ex
|
144
124
|
if (refresh_count += 1) < 3
|
145
|
-
Rails.logger.info("[#{self.id}] REFRESH TASK - Failed Retrying(#{refresh_count})")
|
146
125
|
if ex.code == 401
|
147
126
|
self.refresh_oauth
|
148
127
|
end
|
149
128
|
retry
|
150
129
|
else
|
151
|
-
Rails.logger.fatal("[#{self.id}] REFRESH TASK - Failed #{refresh_count}x")
|
152
130
|
raise
|
153
131
|
end
|
154
132
|
end
|
155
133
|
|
156
134
|
#### START Task Mathods ####
|
157
135
|
def build_task(task_data, session)
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
if
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
tmp.client(entity_id).current_session = session["#{self.id}::#{k}::#{entity_id}:session"] if !session.nil? && v["tenant_type"] == "Zuora" && session["#{self.id}::#{k}::#{entity_id}:session"]
|
169
|
-
end
|
170
|
-
else
|
171
|
-
tmp.client.current_session = session["#{self.id}::#{k}:session"] if !session.nil? && v["tenant_type"] == "Zuora" && session["#{self.id}::#{k}:session"]
|
136
|
+
@task_data = task_data
|
137
|
+
@mode = @task_data["mode"]
|
138
|
+
@task_data.each do |k,v|
|
139
|
+
if k.match(/^(.*)_login$/)
|
140
|
+
tmp = ZuoraConnect::Login.new(v)
|
141
|
+
if !session.nil? && v["tenant_type"] == "Zuora"
|
142
|
+
if tmp.entities.size > 0
|
143
|
+
tmp.entities.each do |value|
|
144
|
+
entity_id = value["id"]
|
145
|
+
tmp.client(entity_id).current_session = session["#{self.id}::#{k}::#{entity_id}:session"] if !session.nil? && v["tenant_type"] == "Zuora" && session["#{self.id}::#{k}::#{entity_id}:session"]
|
172
146
|
end
|
147
|
+
else
|
148
|
+
tmp.client.current_session = session["#{self.id}::#{k}:session"] if !session.nil? && v["tenant_type"] == "Zuora" && session["#{self.id}::#{k}:session"]
|
173
149
|
end
|
174
|
-
@logins[k] = tmp
|
175
|
-
self.attr_builder(k, @logins[k])
|
176
|
-
elsif k == "options"
|
177
|
-
v.each do |opt|
|
178
|
-
@options[opt["config_name"]] = opt
|
179
|
-
end
|
180
|
-
elsif k == "user_settings"
|
181
|
-
self.timezone = v["timezone"]
|
182
|
-
self.locale = v["local"]
|
183
150
|
end
|
151
|
+
@logins[k] = tmp
|
152
|
+
self.attr_builder(k, @logins[k])
|
153
|
+
elsif k == "options"
|
154
|
+
v.each do |opt|
|
155
|
+
@options[opt["config_name"]] = opt
|
156
|
+
end
|
157
|
+
elsif k == "user_settings"
|
158
|
+
self.timezone = v["timezone"]
|
159
|
+
self.locale = v["local"]
|
184
160
|
end
|
185
|
-
rescue => ex
|
186
|
-
Rails.logger.error("Task Data: #{task_data}")
|
187
|
-
Rails.logger.error("Task Session: #{session.to_hash}")
|
188
|
-
raise
|
189
161
|
end
|
162
|
+
Thread.current[:appinstance] = self
|
190
163
|
end
|
191
164
|
|
192
165
|
def updateOption(optionId, value)
|
@@ -197,17 +170,10 @@ module ZuoraConnect
|
|
197
170
|
#EXAMPLE: {"name": "ftp_login_14","username": "ftplogin7","tenant_type": "Custom","password": "test2","url": "www.ftp.com","custom_data": { "path": "/var/usr/test"}}
|
198
171
|
def update_logins(options)
|
199
172
|
update_login_count ||= 0
|
173
|
+
|
200
174
|
response = HTTParty.post(ZuoraConnect.configuration.url + "/api/#{self.api_version}/tools/tasks/#{self.id}/logins",:body => {:access_token => self.username}.merge(options))
|
201
|
-
parsed_json = JSON.parse(response.body)
|
202
175
|
if response.code == 200
|
203
|
-
|
204
|
-
self.build_task(parsed_json, self.data_lookup)
|
205
|
-
self.last_refresh = Time.now.to_i
|
206
|
-
self.cache_app_instance
|
207
|
-
end
|
208
|
-
return parsed_json
|
209
|
-
elsif response.code == 400
|
210
|
-
raise ZuoraConnect::Exceptions::APIError.new(message: parsed_json['errors'].join(' '), response: response.body, code: response.code)
|
176
|
+
return JSON.parse(response.body)
|
211
177
|
else
|
212
178
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
|
213
179
|
end
|
@@ -232,14 +198,12 @@ module ZuoraConnect
|
|
232
198
|
#### START Connect OAUTH methods ####
|
233
199
|
def check_oauth_state(method)
|
234
200
|
#Refresh token if already expired
|
235
|
-
|
236
|
-
|
237
|
-
self.refresh_oauth
|
238
|
-
end
|
201
|
+
Rails.logger.debug("[#{self.id}] Before '#{method}' method check Oauth state")
|
202
|
+
self.refresh_oauth if self.oauth_expired?
|
239
203
|
end
|
240
204
|
|
241
205
|
def oauth_expired?
|
242
|
-
|
206
|
+
(self.oauth_expires_at < Time.now)
|
243
207
|
end
|
244
208
|
|
245
209
|
def refresh_oauth
|
@@ -268,21 +232,15 @@ module ZuoraConnect
|
|
268
232
|
end
|
269
233
|
rescue Net::ReadTimeout, Net::OpenTimeout, Errno::EPIPE, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => ex
|
270
234
|
if (refresh_oauth_count += 1) < 3
|
271
|
-
Rails.logger.info("[#{self.id}] REFRESH OAUTH - #{ex.class} Retrying(#{refresh_oauth_count})")
|
272
235
|
retry
|
273
236
|
else
|
274
|
-
Rails.logger.fatal("[#{self.id}] REFRESH OAUTH - #{ex.class} Failed #{refresh_oauth_count}x")
|
275
237
|
raise
|
276
238
|
end
|
277
239
|
rescue ZuoraConnect::Exceptions::ConnectCommunicationError => ex
|
278
|
-
sleep(5)
|
279
|
-
self.reload_attributes([:refresh_token, :oauth_expires_at, :access_token]) #Reload only the refresh token for retry
|
280
|
-
|
281
|
-
#After reload, if nolonger expired return
|
282
|
-
return if !self.oauth_expired?
|
283
|
-
|
284
240
|
if (refresh_oauth_count += 1) < 3
|
285
241
|
Rails.logger.info("[#{self.id}] REFRESH OAUTH - Failed Retrying(#{refresh_oauth_count})")
|
242
|
+
sleep(5)
|
243
|
+
self.reload_attributes([:refresh_token]) #Refload only the refresh token for retry
|
286
244
|
retry
|
287
245
|
else
|
288
246
|
Rails.logger.fatal("[#{self.id}] REFRESH OAUTH - Failed #{refresh_oauth_count}x")
|
@@ -300,16 +258,12 @@ module ZuoraConnect
|
|
300
258
|
Redis.current.del("AppInstance:#{self.id}:Refreshing") if defined?(Redis.current)
|
301
259
|
end
|
302
260
|
|
303
|
-
def
|
261
|
+
def refreshed_at
|
304
262
|
return defined?(Redis.current) ? REFRESH_TIMEOUT.to_i - Redis.current.ttl("AppInstance:#{self.id}:Refreshing") : 0
|
305
263
|
end
|
306
264
|
|
307
|
-
def
|
308
|
-
|
309
|
-
end
|
310
|
-
|
311
|
-
def mark_for_refresh
|
312
|
-
return defined?(Redis.current) ? Redis.current.set("AppInstance:#{self.id}:Refreshing", true, {:nx => true, :ex => REFRESH_TIMEOUT.to_i}) : true
|
265
|
+
def mark_for_refresh
|
266
|
+
Redis.current.setex("AppInstance:#{self.id}:Refreshing", REFRESH_TIMEOUT.to_i, true) if defined?(Redis.current)
|
313
267
|
end
|
314
268
|
|
315
269
|
def data_lookup(session: {})
|
@@ -320,10 +274,10 @@ module ZuoraConnect
|
|
320
274
|
cached_instance = Redis.current.get("AppInstance:#{self.id}")
|
321
275
|
if cached_instance.blank?
|
322
276
|
Rails.logger.debug("[#{self.id}] Cached AppInstance Missing")
|
323
|
-
return
|
277
|
+
return session
|
324
278
|
else
|
325
279
|
Rails.logger.debug("[#{self.id}] Cached AppInstance Found")
|
326
|
-
return decrypt_data(data: cached_instance, rescue_return:
|
280
|
+
return decrypt_data(data: cached_instance, rescue_return: {})
|
327
281
|
end
|
328
282
|
else
|
329
283
|
return session
|
@@ -332,11 +286,7 @@ module ZuoraConnect
|
|
332
286
|
|
333
287
|
def cache_app_instance
|
334
288
|
if defined?(Redis.current)
|
335
|
-
|
336
|
-
if self.task_data.present? && (self.last_refresh.to_i > INSTANCE_REFRESH_WINDOW.ago.to_i)
|
337
|
-
Rails.logger.info("[#{self.id}] Caching AppInstance")
|
338
|
-
Redis.current.setex("AppInstance:#{self.id}", INSTANCE_REDIS_CACHE_PERIOD.to_i, encrypt_data(data: self.save_data))
|
339
|
-
end
|
289
|
+
Redis.current.setex("AppInstance:#{self.id}", INSTANCE_REDIS_CACHE_PERIOD.to_i, encrypt_data(data: self.save_data))
|
340
290
|
Redis.current.del("Deleted:#{self.id}")
|
341
291
|
end
|
342
292
|
end
|
@@ -353,17 +303,7 @@ module ZuoraConnect
|
|
353
303
|
end
|
354
304
|
end
|
355
305
|
end
|
356
|
-
|
357
306
|
session["#{self.id}::task_data"] = self.task_data
|
358
|
-
|
359
|
-
#Redis is not defined strip out old data
|
360
|
-
if !defined?(Redis.current)
|
361
|
-
session["#{self.id}::task_data"].delete('applications')
|
362
|
-
session["#{self.id}::task_data"].select {|k,v| k.include?('login') && v['tenant_type'] == 'Zuora'}.each do |login_key, login_data|
|
363
|
-
session["#{self.id}::task_data"][login_key]['entities'] = (login_data.dig('entities') || []).map {|entity| entity.slice('id', 'tenantId')}
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
307
|
session["#{self.id}::last_refresh"] = self.last_refresh
|
368
308
|
session["appInstance"] = self.id
|
369
309
|
return session
|
@@ -440,11 +380,9 @@ module ZuoraConnect
|
|
440
380
|
|
441
381
|
### START Catalog Helping Methods #####
|
442
382
|
def get_catalog(page_size: 5, zuora_login: self.login_lookup(type: "Zuora").first, entity_id: nil)
|
443
|
-
self.update_column(:catalog_update_attempt_at, Time.now.utc)
|
444
|
-
|
445
383
|
entity_reference = entity_id.blank? ? 'Default' : entity_id
|
446
|
-
Rails.logger.
|
447
|
-
Rails.logger.
|
384
|
+
Rails.logger.info("Fetch Catalog")
|
385
|
+
Rails.logger.info("Zuora Entity: #{entity_id.blank? ? 'default' : entity_id}")
|
448
386
|
|
449
387
|
login = zuora_login.client(entity_reference)
|
450
388
|
|
@@ -526,7 +464,7 @@ module ZuoraConnect
|
|
526
464
|
raise "Object Id can only be a string or an array of strings"
|
527
465
|
end
|
528
466
|
|
529
|
-
if defined?(Redis.current) && object_id.present? && object_id.class == String
|
467
|
+
if defined?(Redis.current) && object_id.present? && object_id.class == String
|
530
468
|
stub_catalog = decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Children:#{child_objects}"))
|
531
469
|
object_hierarchy = decrypt_data(data: Redis.current.get("Catalog:#{self.id}:#{object_id}:Hierarchy"))
|
532
470
|
end
|
@@ -537,7 +475,7 @@ module ZuoraConnect
|
|
537
475
|
|
538
476
|
case object
|
539
477
|
when :product
|
540
|
-
if object_id.
|
478
|
+
if object_id.blank?
|
541
479
|
string =
|
542
480
|
"SELECT "\
|
543
481
|
"json_object_agg(product_id, product #{child_objects ? '' : '- \'productRatePlans\''}) AS item "\
|
@@ -554,7 +492,7 @@ module ZuoraConnect
|
|
554
492
|
"FROM "\
|
555
493
|
"\"public\".\"zuora_connect_app_instances\" "\
|
556
494
|
"WHERE "\
|
557
|
-
"\"id\" = %s" % [entity_reference, object_id
|
495
|
+
"\"id\" = %s" % [entity_reference, object_id, self.id]
|
558
496
|
elsif object_id.class == Array
|
559
497
|
string =
|
560
498
|
"SELECT "\
|
@@ -569,7 +507,7 @@ module ZuoraConnect
|
|
569
507
|
end
|
570
508
|
|
571
509
|
when :rateplan
|
572
|
-
if object_id.
|
510
|
+
if object_id.blank?
|
573
511
|
string =
|
574
512
|
"SELECT "\
|
575
513
|
"json_object_agg(rateplan_id, rateplan #{child_objects ? '' : '- \'productRatePlanCharges\''}) AS item "\
|
@@ -587,7 +525,7 @@ module ZuoraConnect
|
|
587
525
|
"FROM "\
|
588
526
|
"\"public\".\"zuora_connect_app_instances\" "\
|
589
527
|
"WHERE "\
|
590
|
-
"\"id\" = %s" % [entity_reference, object_hierarchy['productId'], object_id
|
528
|
+
"\"id\" = %s" % [entity_reference, object_hierarchy['productId'], object_id, self.id]
|
591
529
|
elsif object_id.class == Array
|
592
530
|
string =
|
593
531
|
"SELECT "\
|
@@ -603,7 +541,7 @@ module ZuoraConnect
|
|
603
541
|
end
|
604
542
|
|
605
543
|
when :charge
|
606
|
-
if object_id.
|
544
|
+
if object_id.blank?
|
607
545
|
string =
|
608
546
|
"SELECT "\
|
609
547
|
"json_object_agg(charge_id, charge) as item "\
|
@@ -622,7 +560,7 @@ module ZuoraConnect
|
|
622
560
|
"FROM "\
|
623
561
|
"\"public\".\"zuora_connect_app_instances\" "\
|
624
562
|
"WHERE "\
|
625
|
-
"\"id\" = %s" % [entity_reference, object_hierarchy['productId'], object_hierarchy['productRatePlanId'], object_id
|
563
|
+
"\"id\" = %s" % [entity_reference, object_hierarchy['productId'], object_hierarchy['productRatePlanId'], object_id, self.id]
|
626
564
|
|
627
565
|
elsif object_id.class == Array
|
628
566
|
string =
|
@@ -644,7 +582,7 @@ module ZuoraConnect
|
|
644
582
|
|
645
583
|
stub_catalog ||= JSON.parse(ActiveRecord::Base.connection.execute(string).first["item"] || "{}")
|
646
584
|
|
647
|
-
if defined?(Redis.current) && object_id.present? && object_id.class == String
|
585
|
+
if defined?(Redis.current) && object_id.present? && object_id.class == String
|
648
586
|
Redis.current.set("Catalog:#{self.id}:#{object_id}:Hierarchy", encrypt_data(data: object_hierarchy))
|
649
587
|
Redis.current.set("Catalog:#{self.id}:#{object_id}:Children:#{child_objects}", encrypt_data(data: stub_catalog)) if cache
|
650
588
|
end
|
@@ -677,7 +615,7 @@ module ZuoraConnect
|
|
677
615
|
### END S3 Helping Methods #####
|
678
616
|
|
679
617
|
### START Aggregate Grouping Helping Methods ####
|
680
|
-
def self.refresh_aggregate_table(aggregate_name: 'all_tasks_processing', table_name: 'tasks', where_clause: "where status in ('Processing', 'Queued')", index_table: true)
|
618
|
+
def self.refresh_aggregate_table(aggregate_name: 'all_tasks_processing', table_name: 'tasks', where_clause: "where status in ('Processing', 'Queued')", index_table: true)
|
681
619
|
self.update_functions
|
682
620
|
#Broke function into two parts to ensure transaction size was small enough
|
683
621
|
ActiveRecord::Base.connection.execute('SELECT "shared_extensions".refresh_aggregate_table(\'%s\', \'%s\', %s, \'Table\');' % [aggregate_name, table_name, ActiveRecord::Base.connection.quote(where_clause)])
|
@@ -689,18 +627,6 @@ module ZuoraConnect
|
|
689
627
|
end
|
690
628
|
### END Aggregate Grouping Helping Methods #####
|
691
629
|
|
692
|
-
# Overide this method to avoid the new session call for api requests that use the before filter authenticate_app_api_request.
|
693
|
-
# This can be usefull for apps that dont need connect metadata call, or credentials, to operate for api requests
|
694
|
-
def new_session_for_api_requests(params: {})
|
695
|
-
return true
|
696
|
-
end
|
697
|
-
|
698
|
-
# Overide this method to avoid the new session call for ui requests that use the before filter authenticate_connect_app_request.
|
699
|
-
# This can be usefull for apps that dont need connect metadata call, or credentials, to operate for ui requests
|
700
|
-
def new_session_for_ui_requests(params: {})
|
701
|
-
return true
|
702
|
-
end
|
703
|
-
|
704
630
|
def reload_attributes(selected_attributes)
|
705
631
|
raise "Attibutes must be array" if selected_attributes.class != Array
|
706
632
|
value_attributes = self.class.unscoped.where(:id=>id).select(selected_attributes).first.attributes
|
@@ -745,6 +671,5 @@ module ZuoraConnect
|
|
745
671
|
end
|
746
672
|
|
747
673
|
method_hook :refresh, :updateOption, :update_logins, :before => :check_oauth_state
|
748
|
-
method_hook :new_session, :refresh, :build_task, :after => :apartment_switch
|
749
674
|
end
|
750
675
|
end
|
@@ -1,6 +1,6 @@
|
|
1
|
-
redis_url = ENV["REDIS_URL"].present? ? ENV["REDIS_URL"] :
|
1
|
+
redis_url = ENV["REDIS_URL"].present? ? ENV["REDIS_URL"] : 'redis://localhost:6379/1'
|
2
2
|
if defined?(Redis.current)
|
3
|
-
Redis.current = Redis.new(:url => redis_url, :timeout => 10
|
3
|
+
Redis.current = Redis.new(:url => redis_url, :timeout => 10)
|
4
4
|
if defined?(Resque.redis)
|
5
5
|
Resque.redis = Redis.current
|
6
6
|
end
|
@@ -38,29 +38,18 @@ module Resque
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def reserve_with_round_robin
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
@n = @n % grouped_queues.keys.size
|
48
|
-
|
49
|
-
grouped_queues.keys.rotate(@n).each do |key|
|
50
|
-
grouped_queues[key].each do |queue|
|
51
|
-
log! "Checking #{queue}"
|
52
|
-
if should_work_on_queue?(queue) && @job_in_progress = Resque::Job.reserve(queue)
|
53
|
-
log! "Found job on #{queue}"
|
54
|
-
return @job_in_progress
|
55
|
-
end
|
56
|
-
end
|
57
|
-
@n += 1 # Start the next search at the queue after the one from which we pick a job.
|
41
|
+
qs = rotated_queues
|
42
|
+
qs.each do |queue|
|
43
|
+
log! "Checking #{queue}"
|
44
|
+
if should_work_on_queue?(queue) && @job_in_progress = Resque::Job.reserve(queue)
|
45
|
+
log! "Found job on #{queue}"
|
46
|
+
return @job_in_progress
|
58
47
|
end
|
59
|
-
|
60
|
-
|
61
|
-
return reserve_without_round_robin
|
48
|
+
# Start the next search at the queue after the one from which we pick a job.
|
49
|
+
@n += 1
|
62
50
|
end
|
63
|
-
|
51
|
+
|
52
|
+
nil
|
64
53
|
rescue Exception => e
|
65
54
|
log "Error reserving job: #{e.inspect}"
|
66
55
|
log e.backtrace.join("\n")
|
@@ -90,7 +79,7 @@ module Resque
|
|
90
79
|
|
91
80
|
#Remove Queues under Api Limits
|
92
81
|
api_limit_instances = Redis.current.keys('APILimits:*').map {|key| key.split('APILimits:').last.to_i}
|
93
|
-
real_queues = real_queues.select {|key| key if !api_limit_instances.include?((key.match(/^(\d*)_.*/) || [])[1].to_i)}
|
82
|
+
real_queues = real_queues.select {|key| key if !api_limit_instances.include?((key.match(/^(\d*)_.*/) || [])[1].to_i)}
|
94
83
|
|
95
84
|
#Queue Pausing
|
96
85
|
paused_instances = Redis.current.keys('resque:PauseQueue:*').map {|key| key.split('resque:PauseQueue:').last.to_i}
|
@@ -6,7 +6,6 @@ module ZuoraConnect
|
|
6
6
|
|
7
7
|
def authenticate_app_api_request
|
8
8
|
#Skip session for api requests
|
9
|
-
Thread.current[:appinstance] = nil
|
10
9
|
request.session_options[:skip] = true
|
11
10
|
start_time = Time.now
|
12
11
|
if request.headers["API-Token"].present?
|
@@ -25,8 +24,8 @@ module ZuoraConnect
|
|
25
24
|
end
|
26
25
|
|
27
26
|
def authenticate_connect_app_request
|
28
|
-
Thread.current[:appinstance] = nil
|
29
27
|
start_time = Time.now
|
28
|
+
|
30
29
|
if ZuoraConnect.configuration.mode == "Production"
|
31
30
|
if request["data"]
|
32
31
|
setup_instance_via_data
|
@@ -39,9 +38,7 @@ module ZuoraConnect
|
|
39
38
|
#Call .data_lookup with the current session to retrieve session. In some cases session may be stored/cache in redis
|
40
39
|
#so data lookup provides a model method that can be overriden per app.
|
41
40
|
if params[:controller] != 'zuora_connect/api/v1/app_instance' && params[:action] != 'drop'
|
42
|
-
|
43
|
-
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
44
|
-
end
|
41
|
+
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
45
42
|
end
|
46
43
|
PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail) && session["#{@appinstance.id}::user::email"].present?
|
47
44
|
begin
|
@@ -55,7 +52,7 @@ module ZuoraConnect
|
|
55
52
|
|
56
53
|
def persist_connect_app_session
|
57
54
|
if @appinstance.present?
|
58
|
-
if defined?(Redis.current)
|
55
|
+
if defined?(Redis.current) && Rails.application.config.session_store.to_s == "RedisSessionStore"
|
59
56
|
@appinstance.cache_app_instance
|
60
57
|
else
|
61
58
|
session.merge!(@appinstance.save_data)
|
@@ -150,9 +147,7 @@ module ZuoraConnect
|
|
150
147
|
#API ONLY
|
151
148
|
def check_instance
|
152
149
|
if @appinstance.present?
|
153
|
-
|
154
|
-
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
155
|
-
end
|
150
|
+
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
156
151
|
Thread.current[:appinstance] = @appinstance
|
157
152
|
PaperTrail.whodunnit = "API User" if defined?(PaperTrail)
|
158
153
|
return true
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module ZuoraConnect
|
2
2
|
module Exceptions
|
3
|
-
|
4
|
-
class HoldingPattern < StandardError; end
|
5
3
|
class Error < StandardError; end
|
6
4
|
class AuthorizationNotPerformed < Error; end
|
7
5
|
|
@@ -34,23 +32,6 @@ module ZuoraConnect
|
|
34
32
|
end
|
35
33
|
end
|
36
34
|
|
37
|
-
class APIError < Error
|
38
|
-
attr_reader :code, :response
|
39
|
-
attr_writer :default_message
|
40
|
-
|
41
|
-
def initialize(message: nil,response: nil, code: nil)
|
42
|
-
@code = code
|
43
|
-
@message = message
|
44
|
-
@response = response
|
45
|
-
@default_message = "Connect update error."
|
46
|
-
end
|
47
|
-
|
48
|
-
def to_s
|
49
|
-
@message || @default_message
|
50
|
-
end
|
51
|
-
|
52
|
-
end
|
53
|
-
|
54
35
|
class AccessDenied < Error
|
55
36
|
attr_writer :default_message
|
56
37
|
|
@@ -23,7 +23,7 @@ module ZuoraConnect
|
|
23
23
|
Rails.configuration.lograge.custom_options = lambda do |event|
|
24
24
|
exceptions = %w(controller action format id)
|
25
25
|
{
|
26
|
-
appinstance_id: Thread.current[:appinstance].present? ? Thread.current[:appinstance].id :
|
26
|
+
appinstance_id: Thread.current[:appinstance].present? ? Thread.current[:appinstance].id : "Unknown",
|
27
27
|
params: event.payload[:params].except(*exceptions),
|
28
28
|
exception: event.payload[:exception],
|
29
29
|
exception_object: event.payload[:exception_object]
|
metadata
CHANGED
@@ -1,23 +1,20 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: zuora_connect
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.5.
|
4
|
+
version: 1.5.302
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Connect Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apartment
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
|
-
- !ruby/object:Gem::Version
|
19
|
-
version: '1.2'
|
20
|
-
- - ">="
|
21
18
|
- !ruby/object:Gem::Version
|
22
19
|
version: 1.2.0
|
23
20
|
type: :runtime
|
@@ -25,9 +22,6 @@ dependencies:
|
|
25
22
|
version_requirements: !ruby/object:Gem::Requirement
|
26
23
|
requirements:
|
27
24
|
- - "~>"
|
28
|
-
- !ruby/object:Gem::Version
|
29
|
-
version: '1.2'
|
30
|
-
- - ">="
|
31
25
|
- !ruby/object:Gem::Version
|
32
26
|
version: 1.2.0
|
33
27
|
- !ruby/object:Gem::Dependency
|
@@ -35,9 +29,6 @@ dependencies:
|
|
35
29
|
requirement: !ruby/object:Gem::Requirement
|
36
30
|
requirements:
|
37
31
|
- - "~>"
|
38
|
-
- !ruby/object:Gem::Version
|
39
|
-
version: '1.4'
|
40
|
-
- - ">="
|
41
32
|
- !ruby/object:Gem::Version
|
42
33
|
version: 1.4.0
|
43
34
|
type: :runtime
|
@@ -45,9 +36,6 @@ dependencies:
|
|
45
36
|
version_requirements: !ruby/object:Gem::Requirement
|
46
37
|
requirements:
|
47
38
|
- - "~>"
|
48
|
-
- !ruby/object:Gem::Version
|
49
|
-
version: '1.4'
|
50
|
-
- - ">="
|
51
39
|
- !ruby/object:Gem::Version
|
52
40
|
version: 1.4.0
|
53
41
|
- !ruby/object:Gem::Dependency
|
@@ -182,20 +170,6 @@ dependencies:
|
|
182
170
|
- - ">="
|
183
171
|
- !ruby/object:Gem::Version
|
184
172
|
version: '0'
|
185
|
-
- !ruby/object:Gem::Dependency
|
186
|
-
name: derailed
|
187
|
-
requirement: !ruby/object:Gem::Requirement
|
188
|
-
requirements:
|
189
|
-
- - ">="
|
190
|
-
- !ruby/object:Gem::Version
|
191
|
-
version: '0'
|
192
|
-
type: :development
|
193
|
-
prerelease: false
|
194
|
-
version_requirements: !ruby/object:Gem::Requirement
|
195
|
-
requirements:
|
196
|
-
- - ">="
|
197
|
-
- !ruby/object:Gem::Version
|
198
|
-
version: '0'
|
199
173
|
- !ruby/object:Gem::Dependency
|
200
174
|
name: pg
|
201
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -251,7 +225,6 @@ files:
|
|
251
225
|
- db/migrate/20110503003602_add_catalog_data_to_app_instance.rb
|
252
226
|
- db/migrate/20110503003603_add_catalog_mappings_to_app_instance.rb
|
253
227
|
- db/migrate/20110503003604_catalog_default.rb
|
254
|
-
- db/migrate/20180301052853_add_catalog_attempted_at.rb
|
255
228
|
- lib/resque/additions.rb
|
256
229
|
- lib/resque/dynamic_queues.rb
|
257
230
|
- lib/resque/self_lookup.rb
|
@@ -329,44 +302,44 @@ signing_key:
|
|
329
302
|
specification_version: 4
|
330
303
|
summary: Summary of Connect.
|
331
304
|
test_files:
|
305
|
+
- test/lib/generators/zuora_connect/datatable_generator_test.rb
|
306
|
+
- test/models/zuora_connect/app_instance_test.rb
|
307
|
+
- test/test_helper.rb
|
308
|
+
- test/fixtures/zuora_connect/app_instances.yml
|
332
309
|
- test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
|
333
|
-
- test/
|
310
|
+
- test/integration/navigation_test.rb
|
311
|
+
- test/zuora_connect_test.rb
|
312
|
+
- test/dummy/Rakefile
|
313
|
+
- test/dummy/bin/rails
|
334
314
|
- test/dummy/bin/bundle
|
335
315
|
- test/dummy/bin/setup
|
336
|
-
- test/dummy/bin/
|
337
|
-
- test/dummy/Rakefile
|
338
|
-
- test/dummy/public/favicon.ico
|
339
|
-
- test/dummy/public/404.html
|
340
|
-
- test/dummy/public/422.html
|
341
|
-
- test/dummy/public/500.html
|
342
|
-
- test/dummy/app/controllers/application_controller.rb
|
343
|
-
- test/dummy/app/views/layouts/application.html.erb
|
344
|
-
- test/dummy/app/helpers/application_helper.rb
|
345
|
-
- test/dummy/app/assets/javascripts/application.js
|
346
|
-
- test/dummy/app/assets/stylesheets/application.css
|
316
|
+
- test/dummy/bin/rake
|
347
317
|
- test/dummy/README.rdoc
|
348
|
-
- test/dummy/config.ru
|
349
318
|
- test/dummy/config/locales/en.yml
|
350
|
-
- test/dummy/config/routes.rb
|
351
319
|
- test/dummy/config/environment.rb
|
352
|
-
- test/dummy/config/database.yml
|
353
320
|
- test/dummy/config/secrets.yml
|
321
|
+
- test/dummy/config/database.yml
|
322
|
+
- test/dummy/config/application.rb
|
354
323
|
- test/dummy/config/boot.rb
|
355
324
|
- test/dummy/config/environments/production.rb
|
356
325
|
- test/dummy/config/environments/development.rb
|
357
326
|
- test/dummy/config/environments/test.rb
|
358
|
-
- test/dummy/config/initializers/
|
359
|
-
- test/dummy/config/initializers/filter_parameter_logging.rb
|
360
|
-
- test/dummy/config/initializers/assets.rb
|
361
|
-
- test/dummy/config/initializers/inflections.rb
|
362
|
-
- test/dummy/config/initializers/session_store.rb
|
327
|
+
- test/dummy/config/initializers/cookies_serializer.rb
|
363
328
|
- test/dummy/config/initializers/wrap_parameters.rb
|
329
|
+
- test/dummy/config/initializers/session_store.rb
|
364
330
|
- test/dummy/config/initializers/mime_types.rb
|
365
|
-
- test/dummy/config/initializers/
|
366
|
-
- test/dummy/config/
|
367
|
-
- test/
|
368
|
-
- test/
|
369
|
-
- test/
|
370
|
-
- test/
|
371
|
-
- test/
|
372
|
-
- test/
|
331
|
+
- test/dummy/config/initializers/inflections.rb
|
332
|
+
- test/dummy/config/initializers/assets.rb
|
333
|
+
- test/dummy/config/initializers/filter_parameter_logging.rb
|
334
|
+
- test/dummy/config/initializers/backtrace_silencers.rb
|
335
|
+
- test/dummy/config/routes.rb
|
336
|
+
- test/dummy/public/422.html
|
337
|
+
- test/dummy/public/500.html
|
338
|
+
- test/dummy/public/favicon.ico
|
339
|
+
- test/dummy/public/404.html
|
340
|
+
- test/dummy/app/helpers/application_helper.rb
|
341
|
+
- test/dummy/app/views/layouts/application.html.erb
|
342
|
+
- test/dummy/app/controllers/application_controller.rb
|
343
|
+
- test/dummy/app/assets/stylesheets/application.css
|
344
|
+
- test/dummy/app/assets/javascripts/application.js
|
345
|
+
- test/dummy/config.ru
|