zuora_connect 2.0.60r → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,93 +3,38 @@ if defined? Prometheus
3
3
  require "zuora_connect/version"
4
4
  require "zuora_api/version"
5
5
 
6
- resque_path = "#{ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')}/*.prom"
7
- prometheus_path = Rails.root.join("tmp/prometheus")
8
-
9
- Dir[resque_path, "#{prometheus_path}/*.bin"].each do |file_path|
10
- File.unlink(file_path)
11
- end
12
-
13
- require 'prometheus/client/data_stores/direct_file_store'
14
- Prometheus::Client.config.data_store = Prometheus::Client::DataStores::DirectFileStore.new(
15
- dir: prometheus_path
16
- )
17
-
18
- class ResqueExporter
19
- require 'prometheus/client/formats/text'
20
- require 'fileutils'
21
-
22
- def initialize
23
- @lock = Monitor.new
24
- @registry = Prometheus::Client.registry
25
- @path = ENV['RESQUE_EXPORTER_PATH'] || Rails.root.join('tmp/resque_exporter')
26
- FileUtils.mkdir_p(@path)
27
- end
28
-
29
- def export
30
- filename = File.join(@path, "resque_export_#{Process.pid}.prom")
31
- @lock.synchronize do
32
- File.open(filename, 'w+') do |file|
33
- file.write(Prometheus::Client::Formats::Text.marshal(@registry))
34
- end
35
- end
36
- end
37
- end
38
-
39
- most_recent_aggregation = {}
40
- sum_aggregation = {}
41
- if defined?(Unicorn)
42
- most_recent_aggregation[:aggregation] = :most_recent
43
- sum_aggregation[:aggregation] = :sum
44
- end
45
-
46
6
  # Create a default Prometheus registry for our metrics.
47
7
  prometheus = Prometheus::Client.registry
48
8
 
49
9
  # Create your metrics.
50
- ZUORA_VERSION = prometheus.gauge(:zuora_version, docstring: 'The current Zuora Gem version.', labels: %i(version name), preset_labels: { version: ZuoraAPI::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
51
- CONNECT_VERSION = prometheus.gauge(:gem_version, docstring: 'The current Connect Gem version.', labels: %i(version name), preset_labels: { version: ZuoraConnect::VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
52
- RAILS_VERSION = prometheus.gauge(:rails_version, docstring: 'The current Rails version.', labels: %i(version name), preset_labels: { version: Rails.version, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
53
- RUBY_V = prometheus.gauge(:ruby_version, docstring: 'The current Ruby version.', labels: %i(version name), preset_labels: { version: RUBY_VERSION, name: ZuoraConnect::Telegraf.app_name }, store_settings: most_recent_aggregation)
10
+ ZUORA_VERSION = Prometheus::Client::Gauge.new(:zuora_version, 'The current Zuora Gem version.')
11
+ CONNECT_VERSION = Prometheus::Client::Gauge.new(:gem_version, 'The current Connect Gem version.')
12
+ RAILS_VERSION = Prometheus::Client::Gauge.new(:rails_version, 'The current Rails version.')
13
+ RUBY_V = Prometheus::Client::Gauge.new(:ruby_version, 'The current Ruby version.')
54
14
 
55
- ZUORA_VERSION.set(0)
56
- CONNECT_VERSION.set(0)
57
- RAILS_VERSION.set(0)
58
- RUBY_V.set(0)
15
+ # Register your metrics with the registry we previously created.
16
+ prometheus.register(ZUORA_VERSION);ZUORA_VERSION.set({version: ZuoraAPI::VERSION, name: ZuoraConnect::Telegraf.app_name},0)
17
+ prometheus.register(CONNECT_VERSION);CONNECT_VERSION.set({version: ZuoraConnect::VERSION, name: ZuoraConnect::Telegraf.app_name},0)
18
+ prometheus.register(RAILS_VERSION);RAILS_VERSION.set({version: Rails.version, name: ZuoraConnect::Telegraf.app_name},0)
19
+ prometheus.register(RUBY_V);RUBY_V.set({version: RUBY_VERSION, name: ZuoraConnect::Telegraf.app_name},0)
59
20
 
60
21
  # Do they have resque jobs?
61
22
  if defined? Resque.redis
62
- REDIS_CONNECTION = prometheus.gauge(:redis_connection, docstring: 'The status of the redis connection, 0 or 1', labels: %i(connection name), preset_labels: {connection:'redis', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
63
- JOBS_FINISHED = prometheus.gauge(:jobs_finished, docstring: 'Done resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
64
- WORKERS_TOTAL = prometheus.gauge(:workers_total, docstring: 'Total resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
65
- WORKERS_ACTIVE = prometheus.gauge(:workers_active, docstring: 'Active resque workers', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
66
- JOBS_FAILED = prometheus.gauge(:jobs_failed, docstring: 'Failed resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
67
- JOBS_PENDING = prometheus.gauge(:jobs_pending, docstring: 'Pending resque jobs', labels: %i(type name), preset_labels: {type:'resque', name: ZuoraConnect::Telegraf.app_name}, store_settings: most_recent_aggregation)
68
- end
69
-
70
- if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
71
- UNICORN_KILLS = prometheus.gauge(
72
- :unicorn_kills,
73
- docstring: 'Unicorn Kills',
74
- labels: %i(type name),
75
- preset_labels: {type:'Unicorn-Killer', name: ZuoraConnect::Telegraf.app_name},
76
- store_settings: sum_aggregation
77
- )
23
+ REDIS_CONNECTION = Prometheus::Client::Gauge.new(:redis_connection, 'The status of the redis connection, 0 or 1')
24
+ FINISHED_JOBS = Prometheus::Client::Gauge.new(:finished_jobs, 'Done resque jobs')
25
+ WORKERS = Prometheus::Client::Gauge.new(:workers, 'Total resque workers')
26
+ ACTIVE_WORKERS = Prometheus::Client::Gauge.new(:active_workers, 'Active resque workers')
27
+ FAILED_JOBS = Prometheus::Client::Gauge.new(:failed_jobs, 'Failed resque jobs')
28
+ PENDING_JOBS = Prometheus::Client::Gauge.new(:pending_jobs, 'Pending resque jobs')
29
+
30
+ prometheus.register(REDIS_CONNECTION)
31
+ prometheus.register(FINISHED_JOBS)
32
+ prometheus.register(ACTIVE_WORKERS)
33
+ prometheus.register(WORKERS)
34
+ prometheus.register(FAILED_JOBS)
35
+ prometheus.register(PENDING_JOBS)
78
36
 
79
- ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, _|
80
- gauge_name = "unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_')
81
- gauge = prometheus.gauge(
82
- gauge_name.to_sym,
83
- docstring: 'Unicorn Stats',
84
- labels: %i(type name),
85
- preset_labels: { type: 'unicorn', name: ZuoraConnect::Telegraf.app_name },
86
- store_settings: most_recent_aggregation
87
- )
88
- Prometheus.const_set(
89
- gauge_name.upcase,
90
- gauge
91
- )
92
- end
93
37
  end
38
+
94
39
  end
95
40
  end
@@ -5,20 +5,6 @@ if defined?(Resque::Worker)
5
5
  Resque::Job.send(:include, Resque::SelfLookup)
6
6
  end
7
7
 
8
- if defined?(Resque::Job) && defined?(Prometheus)
9
- module ResquePrometheusExtensions
10
- EXPORTER = Prometheus::ResqueExporter.new
11
- def perform
12
- super
13
- EXPORTER.export
14
- end
15
- end
16
-
17
- class Resque::Job
18
- prepend ResquePrometheusExtensions
19
- end
20
- end
21
-
22
8
  Resque.module_eval do
23
9
  # Returns a hash, mapping queue names to queue sizes
24
10
  def queue_sizes
@@ -3,35 +3,7 @@ if defined?(Unicorn::WorkerKiller)
3
3
  self.singleton_class.send(:alias_method, :kill_self_old, :kill_self)
4
4
  def self.kill_self(logger, start_time)
5
5
  self.kill_self_old(logger, start_time)
6
- if defined?(Prometheus)
7
- Prometheus::UNICORN_KILLS.set(1)
8
- else
9
- ZuoraConnect::AppInstance.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
10
- end
6
+ ZuoraConnect::AppInstance.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
11
7
  end
12
8
  end
13
- end
14
-
15
- if defined?(Unicorn::HttpServer) && defined?(Prometheus)
16
- module HttpServerExtensions
17
- def kill_worker(signal, wpid)
18
- Prometheus::UNICORN_KILLS.increment
19
- super
20
- end
21
- end
22
-
23
- module WorkerExtensions
24
- def soft_kill(sig)
25
- Prometheus::UNICORN_KILLS.increment
26
- super
27
- end
28
- end
29
-
30
- class Unicorn::HttpServer
31
- prepend HttpServerExtensions
32
- end
33
-
34
- class Unicorn::Worker
35
- prepend WorkerExtensions
36
- end
37
9
  end
@@ -3,11 +3,6 @@ ZuoraConnect::Engine.routes.draw do
3
3
  get '/internal/data' => 'static#metrics'
4
4
  post '/initialize_app' => 'static#initialize_app'
5
5
 
6
- if ENV['PROVISION_USER'].present? && ENV['PROVISION_SECRET'].present?
7
- post '/provision' => 'static#provision'
8
- get '/instance/:id/user' => 'static#instance_user'
9
- end
10
-
11
6
  namespace :api do
12
7
  namespace :v1 do
13
8
  resources :app_instance, :only => [:index], defaults: {format: :json} do
@@ -7,7 +7,7 @@ module ZuoraConnect
7
7
  def call(env)
8
8
  begin
9
9
  @app.call(env)
10
- rescue DynamicRailsError => error
10
+ rescue ActionDispatch::ParamsParser::ParseError => error
11
11
  if env['HTTP_ACCEPT'] =~ /application\/json/ || env['CONTENT_TYPE'] =~ /application\/json/
12
12
  return [
13
13
  400, { "Content-Type" => "application/json" },
@@ -18,16 +18,5 @@ module ZuoraConnect
18
18
  end
19
19
  end
20
20
  end
21
-
22
- # Note(hartley): remove once the minimum supported version of Rails is 5.2
23
- class DynamicRailsError < StandardError
24
- def self.===(exception)
25
- if Rails.version >= "5.2"
26
- exception.is_a?(ActionDispatch::Http::Parameters::ParseError)
27
- else
28
- exception.is_a?(ActionDispatch::ParamsParser::ParseError)
29
- end
30
- end
31
- end
32
21
  end
33
- end
22
+ end
@@ -64,22 +64,6 @@ module ZuoraConnect
64
64
  #Remove bad headers
65
65
  @bad_headers.each { |header| env.delete(header) }
66
66
 
67
- if defined?(Prometheus) && env['PATH_INFO'] == '/connect/internal/metrics'
68
- # Prometheus Stuff
69
- metrics = ZuoraConnect::AppInstance.get_metrics('stats')
70
- redis_up = metrics.present? && metrics.dig(:Resque, :Workers_Total).present? ? 1 : 0
71
- Prometheus::REDIS_CONNECTION.set(redis_up)
72
-
73
- process_prometheus_metric(metrics: metrics)
74
-
75
- if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
76
- ZuoraConnect::AppInstanceBase.unicorn_listener_stats.each do |key, value|
77
- gauge = Prometheus.const_get("unicorn_#{key}".gsub(/[^a-zA-Z0-9_]/, '_').upcase)
78
- gauge.set(value) if gauge.present?
79
- end
80
- end
81
- end
82
-
83
67
  #Thread.current[:appinstance] = nil
84
68
  start_time = Time.now
85
69
  begin
@@ -93,6 +77,35 @@ module ZuoraConnect
93
77
  ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: 'request-inbound-assets', tags: tags, values: values)
94
78
  end
95
79
 
80
+ if defined? Prometheus
81
+ #Prometheus Stuff
82
+ if env['PATH_INFO'] == '/connect/internal/metrics'
83
+
84
+ #Do something before each scrape
85
+ if defined? Resque.redis
86
+ begin
87
+
88
+ Resque.redis.ping
89
+
90
+ Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},1)
91
+ Prometheus::FINISHED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:processed])
92
+ Prometheus::PENDING_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:pending])
93
+ Prometheus::ACTIVE_WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:working])
94
+ Prometheus::WORKERS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:workers])
95
+ Prometheus::FAILED_JOBS.set({type:'resque',name: ZuoraConnect::Telegraf.app_name},Resque.info[:failed])
96
+
97
+ rescue Redis::CannotConnectError
98
+ Prometheus::REDIS_CONNECTION.set({connection:'redis',name: ZuoraConnect::Telegraf.app_name},0)
99
+ end
100
+
101
+ if ZuoraConnect.configuration.custom_prometheus_update_block != nil
102
+ ZuoraConnect.configuration.custom_prometheus_update_block.call()
103
+ end
104
+ end
105
+
106
+ end
107
+ end
108
+
96
109
  # Uncomment following block of code for handling engine requests/requests without controller
97
110
  # else
98
111
  # # Handling requests which do not have controllers (engines)
@@ -106,10 +119,10 @@ module ZuoraConnect
106
119
  content_type = @headers['Content-Type'].split(';')[0] if @headers['Content-Type']
107
120
  content_type = content_type.gsub('text/javascript', 'application/javascript')
108
121
  tags = {status: @status, content_type: content_type}
109
-
122
+
110
123
  tags = tags.merge({controller: 'ActionController'})
111
124
  tags = tags.merge({action: 'RoutingError' }) if @status == 404
112
-
125
+
113
126
  values = {response_time: ((Time.now - start_time)*1000).round(2) }
114
127
 
115
128
  ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
@@ -120,32 +133,5 @@ module ZuoraConnect
120
133
  [@status, @headers, @response]
121
134
  end
122
135
  end
123
-
124
- def process_prometheus_metric(type: 'none', metrics: {})
125
- return if metrics.blank?
126
-
127
- prometheus = Prometheus::Client.registry
128
- most_recent_aggregation = {}
129
- if Prometheus::Client.config.data_store.is_a?(Prometheus::Client::DataStores::DirectFileStore)
130
- most_recent_aggregation[:aggregation] = :most_recent
131
- end
132
- metrics.each do |key, value|
133
- next if %w[app_name url].include?(key.to_s)
134
-
135
- if value.is_a?(Hash)
136
- process_prometheus_metric(type: key.to_s, metrics: value)
137
- else
138
- gauge_name = key.to_s.downcase.gsub(/[^a-z0-9_]/, '_')
139
- gauge = prometheus.get(gauge_name.to_sym) || prometheus.gauge(
140
- gauge_name.to_sym,
141
- docstring: "#{key} metric",
142
- labels: %i(type name),
143
- preset_labels: { type: type, name: ZuoraConnect::Telegraf.app_name },
144
- store_settings: most_recent_aggregation
145
- )
146
- gauge.set(value)
147
- end
148
- end
149
- end
150
136
  end
151
137
  end
@@ -92,7 +92,7 @@ module Resque
92
92
  log_with_severity :error, "Error reserving job: #{ex.inspect}"
93
93
  log_with_severity :error, ex.backtrace.join("\n")
94
94
  end
95
- raise ex
95
+ raise e
96
96
  end
97
97
 
98
98
  def create_job(queue, payload)
@@ -12,14 +12,14 @@ module Resque
12
12
  when "Hash"
13
13
  data = args.merge({:worker_class => self.to_s})
14
14
  end
15
- if Rails.logger.is_a?(Ougai::Logger)
15
+ if Rails.logger.is_a?(Ougai::Logger)
16
16
  Rails.logger.with_fields = {job: data, trace_id: SecureRandom.uuid, name: "RailsWorker"}
17
17
  end
18
18
 
19
19
  begin
20
- connection_count ||= 0
20
+ connection_count ||= 0
21
21
  @appinstance = ZuoraConnect::AppInstance.find(args['app_instance_id'].to_i)
22
- Rails.logger.info('Starting job')
22
+ job_start_log(args)
23
23
 
24
24
  @appinstance.new_session(holding_pattern: true)
25
25
  rescue ActiveRecord::RecordNotFound => exception
@@ -52,12 +52,12 @@ module Resque
52
52
  return
53
53
  rescue ZuoraConnect::Exceptions::ConnectCommunicationError => exception
54
54
  Rails.logger.warn("Enqueue Job Again ~ 2 mins", exception)
55
- @appinstance.queue_pause(time: 2.minutes.to_i)
55
+ @appinstance.queue_pause(time: 2.minutes.to_i)
56
56
  Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
57
57
  return
58
58
  rescue Net::ReadTimeout, Net::OpenTimeout, Errno::ECONNRESET, Errno::ECONNREFUSED, SocketError => exception
59
59
  Rails.logger.warn("Enqueue Job Again ~ 2 mins", exception)
60
- @appinstance.queue_pause(time: 2.minutes.to_i)
60
+ @appinstance.queue_pause(time: 2.minutes.to_i)
61
61
  Resque.enqueue_to(self.job.queue, self.job.payload['class'], args)
62
62
  return
63
63
  end
@@ -68,6 +68,10 @@ module Resque
68
68
  @appinstance.cache_app_instance if defined?(@appinstance)
69
69
  Rails.logger.flush if Rails.logger.methods.include?(:flush)
70
70
  end
71
+
72
+ def job_start_log(args)
73
+ Rails.logger.info("Starting job")
74
+ end
71
75
  end
72
76
  end
73
- end
77
+ end
@@ -13,9 +13,6 @@ require 'logging/connect_formatter'
13
13
  require 'metrics/influx/point_value'
14
14
  require 'metrics/net'
15
15
  require 'mono_logger'
16
- require 'zuora_connect/zuora_audit'
17
- require 'active_record'
18
- ::ActiveRecord::Base.send :include, ZuoraConnect::ZuoraAudit
19
16
 
20
17
  module ZuoraConnect
21
18
  class << self
@@ -124,24 +124,14 @@ module ZuoraConnect
124
124
  ElasticAPM.set_user(session["#{@appinstance.id}::user::email"]) if defined?(ElasticAPM) && ElasticAPM.running?
125
125
  PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail)
126
126
  end
127
-
128
- locale = (session["#{@appinstance.id}::user::locale"] || "").gsub("_", "-")
129
127
  begin
128
+ locale = session["#{@appinstance.id}::user::locale"]
130
129
  I18n.locale = locale.present? ? locale : @appinstance.locale
131
130
  rescue I18n::InvalidLocale => ex
132
- if locale.include?("-")
133
- locale = locale.split("-").first
134
- retry
135
- elsif locale != session["#{@appinstance.id}::user::language"]
136
- locale = session["#{@appinstance.id}::user::language"]
137
- retry
138
- end
139
131
  ZuoraConnect.logger.error(ex) if !ZuoraConnect::AppInstance::IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
140
132
  end
141
133
  begin
142
- if @appinstance.user_timezone.blank?
143
- Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
144
- end
134
+ Time.zone = session["#{@appinstance.id}::user::timezone"] ? session["#{@appinstance.id}::user::timezone"] : @appinstance.timezone
145
135
  rescue
146
136
  ZuoraConnect.logger.error(ex)
147
137
  end
@@ -229,80 +219,6 @@ module ZuoraConnect
229
219
  return (request.headers['ZuoraCurrentEntity'].present? || cookies['ZuoraCurrentEntity'].present?)
230
220
  end
231
221
 
232
- def create_new_instance
233
- ZuoraConnect::AppInstance.read_master_db do
234
- Thread.current[:appinstance] = nil
235
- ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
236
- Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
237
-
238
- if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
239
- ElasticAPM.set_label(:trace_id, request.uuid)
240
- end
241
-
242
- zuora_host = request.headers['zuora-host']
243
- zuora_entity_id = (request.headers['zuora-entity-ids'] || '').gsub(
244
- '-',
245
- ''
246
- ).split(',').first
247
-
248
- # Validate host present
249
- if zuora_host.blank?
250
- render json: {
251
- status: 401,
252
- message: 'zuora-host header was not supplied.'
253
- }, status: :unauthorized
254
- return
255
- end
256
-
257
- # Validate entity-ids present
258
- if zuora_entity_id.blank?
259
- render json: {
260
- status: 401,
261
- message: 'zuora-entity-ids header was not supplied.'
262
- }, status: :unauthorized
263
- return
264
- end
265
-
266
- rest_domain = ZuoraAPI::Login.new(url: "https://#{zuora_host}").rest_domain
267
- app_instance_id = ZuoraConnect::AppInstance.where(
268
- 'zuora_entity_ids ?& array[:entities] AND zuora_domain = :host',
269
- entities: [zuora_entity_id],
270
- host: rest_domain
271
- ).pluck(:id).first
272
-
273
- if app_instance_id.present?
274
- render json: {
275
- status: 409,
276
- message: 'Instance already exists.',
277
- app_instance_id: app_instance_id
278
- }, status: 409
279
- else
280
- Apartment::Tenant.switch!("public")
281
- retry_count = 3
282
- begin
283
- @appinstance = new_instance(
284
- next_instance_id,
285
- zuora_entity_id,
286
- rest_domain,
287
- retry_count: retry_count
288
- )
289
- rescue ActiveRecord::RecordNotUnique
290
- retry if (retry_count -= 1).positive?
291
- return
292
- end
293
-
294
- app_instance_id = @appinstance.id
295
- end
296
-
297
- begin
298
- Apartment::Tenant.switch!('public')
299
- Apartment::Tenant.create(app_instance_id.to_s)
300
- rescue Apartment::TenantExists
301
- ZuoraConnect.logger.debug('Tenant Already Exists')
302
- end
303
- end
304
- end
305
-
306
222
  private
307
223
  def setup_instance_via_prod_mode
308
224
  zuora_entity_id = request.headers['ZuoraCurrentEntity'] || cookies['ZuoraCurrentEntity']
@@ -310,7 +226,7 @@ module ZuoraConnect
310
226
  if zuora_entity_id.present?
311
227
  zuora_tenant_id = cookies['Zuora-Tenant-Id']
312
228
  zuora_user_id = cookies['Zuora-User-Id']
313
- zuora_host = request.headers['HTTP_X_FORWARDED_HOST'] || request.headers['Zuora-Host'] || 'apisandbox.zuora.com'
229
+ zuora_host = request.headers["HTTP_X_FORWARDED_HOST"] || "apisandbox.zuora.com"
314
230
 
315
231
  zuora_details = {'host' => zuora_host, 'user_id' => zuora_user_id, 'tenant_id' => zuora_tenant_id, 'entity_id' => zuora_entity_id}
316
232
  auth_headers = {}
@@ -412,16 +328,13 @@ module ZuoraConnect
412
328
 
413
329
  zuora_user_id = cookies['Zuora-User-Id'] || session["ZuoraCurrentIdentity"]['userId']
414
330
 
331
+ #One deployed instance
415
332
  if appinstances.size == 1
416
333
  ZuoraConnect.logger.debug("Instance is #{appinstances.to_h.keys.first}")
417
334
  @appinstance = ZuoraConnect::AppInstance.find(appinstances.to_h.keys.first)
418
- end
419
335
 
420
- # One deployed instance with credentials
421
- if defined?(@appinstance) && !@appinstance['zuora_logins'].nil?
422
336
  #Add user/update
423
337
  begin
424
- ZuoraConnect::ZuoraUser.reset_table_name
425
338
  @zuora_user = ZuoraConnect::ZuoraUser.where(:zuora_user_id => zuora_user_id).first
426
339
  rescue ActiveRecord::StatementInvalid => ex
427
340
  if ex.message.include?("PG::UndefinedTable") && ex.message.include?("zuora_users")
@@ -442,12 +355,10 @@ module ZuoraConnect
442
355
  @zuora_user = ZuoraConnect::ZuoraUser.create!(:zuora_user_id => zuora_user_id, :zuora_identity_response => {zuora_entity_id => session["ZuoraCurrentIdentity"]})
443
356
  end
444
357
  @zuora_user.session = session
445
- ZuoraConnect::ZuoraUser.current_user_id = zuora_user_id
446
358
  session["#{@appinstance.id}::user::localUserId"] = @zuora_user.id
447
359
  session["#{@appinstance.id}::user::email"] = session['ZuoraCurrentIdentity']["username"]
448
360
  session["#{@appinstance.id}::user::timezone"] = session['ZuoraCurrentIdentity']["timeZone"]
449
- session["#{@appinstance.id}::user::language"] = session['ZuoraCurrentIdentity']["language"]
450
- session["#{@appinstance.id}::user::locale"] = session['ZuoraCurrentIdentity']["locale"]
361
+ session["#{@appinstance.id}::user::locale"] = session['ZuoraCurrentIdentity']["language"]
451
362
  session["appInstance"] = @appinstance.id
452
363
 
453
364
  #We have multiple, user must pick
@@ -469,85 +380,79 @@ module ZuoraConnect
469
380
  return
470
381
  end
471
382
  Apartment::Tenant.switch!("public")
472
- retry_count = 3
473
- task_data = {}
474
- begin
475
- ActiveRecord::Base.transaction do
476
- ActiveRecord::Base.connection.execute('LOCK public.zuora_users IN ACCESS EXCLUSIVE MODE')
383
+ ActiveRecord::Base.transaction do
384
+ ActiveRecord::Base.connection.execute('LOCK public.zuora_users IN ACCESS EXCLUSIVE MODE')
385
+ appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host", entities: [zuora_entity_id], host: zuora_client.rest_domain).pluck(:id, :name)
477
386
 
478
- unless defined?(@appinstance)
479
- appinstances = ZuoraConnect::AppInstance.where("zuora_entity_ids ?& array[:entities] = true AND zuora_domain = :host", entities: [zuora_entity_id], host: zuora_client.rest_domain).pluck(:id, :name)
480
-
481
- if appinstances.size > 0
482
- redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
483
- return
484
- end
485
- end
387
+ if appinstances.size > 0
388
+ redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
389
+ return
390
+ end
486
391
 
487
- next_id = defined?(@appinstance) ? @appinstance.id : next_instance_id
488
- if task_data.blank?
489
- user = (ENV['DEIS_APP'] || "Application").split('-').map(&:capitalize).join(' ')
490
- body = {
491
- 'userId' => zuora_user_id,
492
- 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
493
- 'customAuthorities' => [],
494
- 'additionalInformation' => {
495
- 'description' => "This user is for #{user} application.",
496
- 'name' => "#{user} API User #{next_id}"
497
- }
498
- }
499
-
500
- oauth_response, response = zuora_client.rest_call(
501
- method: :post,
502
- body: body.to_json,
503
- url: zuora_client.rest_endpoint("genesis/clients").gsub('v1/', ''),
504
- session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
505
- headers: auth_headers
506
- )
507
-
508
- new_zuora_client = ZuoraAPI::Oauth.new(url: "https://#{zuora_host}", oauth_client_id: oauth_response["clientId"], oauth_secret: oauth_response["clientSecret"] )
509
- if session["ZuoraCurrentUserInfo"].blank?
510
- client_describe, response = new_zuora_client.rest_call(url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''), session_type: :bearer)
511
- else
512
- client_describe = session["ZuoraCurrentUserInfo"]
513
- end
392
+ next_id = (ZuoraConnect::AppInstance.all.where('id > 24999999').order(id: :desc).limit(1).pluck(:id).first || 24999999) + 1
393
+ user = (ENV['DEIS_APP'] || "Application").split('-').map(&:capitalize).join(' ')
394
+ body = {
395
+ 'userId' => zuora_user_id,
396
+ 'entityIds' => [zuora_entity_id.unpack("a8a4a4a4a12").join('-')],
397
+ 'customAuthorities' => [],
398
+ 'additionalInformation' => {
399
+ 'description' => "This user is for #{user} application.",
400
+ 'name' => "#{user} API User #{next_id}"
401
+ }
402
+ }
403
+
404
+ oauth_response, response = zuora_client.rest_call(
405
+ method: :post,
406
+ body: body.to_json,
407
+ url: zuora_client.rest_endpoint("genesis/clients").gsub('v1/', ''),
408
+ session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic,
409
+ headers: auth_headers
410
+ )
514
411
 
515
- available_entities = client_describe["accessibleEntities"].select {|entity| entity['id'] == zuora_entity_id}
516
- task_data = {
517
- "id": next_id,
518
- "name": client_describe["tenantName"],
519
- "mode": "Collections",
520
- "status": "Running",
521
- ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION => {
522
- "tenant_type": "Zuora",
523
- "username": session["ZuoraCurrentIdentity"]["username"],
524
- "url": new_zuora_client.url,
525
- "status": "Active",
526
- "oauth_client_id": oauth_response['clientId'],
527
- "oauth_secret": oauth_response['clientSecret'],
528
- "authentication_type": "OAUTH",
529
- "entities": available_entities.map {|e| e.merge({'displayName' => client_describe["tenantName"]})}
530
- },
531
- "tenant_ids": available_entities.map{|e| e['entityId']}.uniq,
532
- }
533
- end
412
+ new_zuora_client = ZuoraAPI::Oauth.new(url: "https://#{zuora_host}", oauth_client_id: oauth_response["clientId"], oauth_secret: oauth_response["clientSecret"] )
413
+ if session["ZuoraCurrentUserInfo"].blank?
414
+ client_describe, response = new_zuora_client.rest_call(url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''), session_type: :bearer)
415
+ else
416
+ client_describe = session["ZuoraCurrentUserInfo"]
417
+ end
534
418
 
535
- if defined?(@appinstance)
536
- @appinstance.zuora_logins = task_data
537
- @appinstance.save(:validate => false)
419
+ available_entities = client_describe["accessibleEntities"].select {|entity| entity['id'] == zuora_entity_id}
420
+ task_data = {
421
+ "id": next_id,
422
+ "name": client_describe["tenantName"],
423
+ "mode": "Collections",
424
+ "status": "Running",
425
+ ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION => {
426
+ "tenant_type": "Zuora",
427
+ "username": session["ZuoraCurrentIdentity"]["username"],
428
+ "url": new_zuora_client.url,
429
+ "status": "Active",
430
+ "oauth_client_id": oauth_response['clientId'],
431
+ "oauth_secret": oauth_response['clientSecret'],
432
+ "authentication_type": "OAUTH",
433
+ "entities": available_entities.map {|e| e.merge({'displayName' => client_describe["tenantName"]})}
434
+ },
435
+ "tenant_ids": available_entities.map{|e| e['entityId']}.uniq,
436
+ }
437
+ mapped_values = {:id => next_id, :api_token => rand(36**64).to_s(36), :token => rand(36**64).to_s(36), :zuora_logins => task_data, :oauth_expires_at => Time.now + 1000.years, :zuora_domain => zuora_client.rest_domain, :zuora_entity_ids => [zuora_entity_id]}
438
+ @appinstance = ZuoraConnect::AppInstance.new(mapped_values)
439
+ retry_count = 0
440
+ begin
441
+ @appinstance.save(:validate => false)
442
+ rescue ActiveRecord::RecordNotUnique => ex
443
+ if (retry_count += 1) < 3
444
+ @appinstance.assign_attributes({:api_token => rand(36**64).to_s(36), :token => rand(36**64).to_s(36)})
445
+ retry
538
446
  else
539
- @appinstance = new_instance(
540
- next_id,
541
- zuora_entity_id,
542
- zuora_client.rest_domain,
543
- task_data: task_data,
544
- retry_count: retry_count
545
- )
447
+ Thread.current[:appinstance] = nil
448
+ session["appInstance"] = nil
449
+ render "zuora_connect/static/error_handled", :locals => {
450
+ :title => "Application could not create unique tokens.",
451
+ :message => "Please contact support or retry launching application."
452
+ }, :layout => false
453
+ return
546
454
  end
547
455
  end
548
- rescue ActiveRecord::RecordNotUnique
549
- retry if (retry_count -= 1).positive?
550
- return
551
456
  end
552
457
 
553
458
  Apartment::Tenant.switch!("public")
@@ -578,8 +483,8 @@ module ZuoraConnect
578
483
 
579
484
  rescue ZuoraAPI::Exceptions::ZuoraAPIError, Exception => ex
580
485
  if ex.message.include?("Referenced User resource(s) not found") && ex.class == ZuoraAPI::Exceptions::ZuoraAPIError
581
- locals = {title: "Provisioning Error", message: "New tenants need to be provisioned by API Gateway('#{ex.message}'). Please contact support."}
582
- render "zuora_connect/static/error_handled", locals: locals, status: 200, layout: false
486
+ locals = {title: "Provisioning Error", message: "New tenats need to be provisioned by API Gateway('#{ex.message}'). Please contact support."}
487
+ render "zuora_connect/static/error_handled", locals: locals, status: 400, layout: false
583
488
  else
584
489
  session.clear
585
490
  if defined?(ex.response) && ex.response.present? && defined?(ex.response.body)
@@ -635,57 +540,12 @@ module ZuoraConnect
635
540
  end
636
541
  end
637
542
 
638
- def next_instance_id
639
- min_instance_id = 24_999_999
640
- (ZuoraConnect::AppInstance.all.where("id > #{min_instance_id}").order(id: :desc).limit(1).pluck(:id).first || min_instance_id) + 1
641
- end
642
-
643
- def new_instance(id, zuora_entity_id, rest_domain, task_data: nil, retry_count: 0)
644
- app_instance = ZuoraConnect::AppInstance.new(
645
- :id => id,
646
- :api_token => generate_token,
647
- :token => generate_token,
648
- :oauth_expires_at => Time.now + 1000.years,
649
- :zuora_domain => rest_domain,
650
- :zuora_entity_ids => [zuora_entity_id]
651
- )
652
-
653
- if task_data.nil?
654
- # no encryption
655
- app_instance['zuora_logins'] = task_data
656
- else
657
- # kms encrypt
658
- app_instance.zuora_logins = task_data
659
- end
660
-
661
- begin
662
- app_instance.save(:validate => false)
663
- rescue ActiveRecord::RecordNotUnique
664
- raise if retry_count > 1
665
-
666
- Thread.current[:appinstance] = nil
667
- session['appInstance'] = nil
668
- render 'zuora_connect/static/error_handled', :locals => {
669
- :title => 'Application could not create unique tokens.',
670
- :message => 'Please contact support or retry launching application.'
671
- }, :layout => false
672
- return
673
- end
674
-
675
- app_instance
676
- end
677
-
678
- def generate_token
679
- rand(36**64).to_s(36)
680
- end
681
-
682
543
  def setup_instance_via_dev_mode
683
544
  session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
684
545
  user = ZuoraConnect.configuration.dev_mode_user
685
546
  key = ZuoraConnect.configuration.dev_mode_pass
686
547
  values = {:user => user , :key => key, :appinstance => session["appInstance"]}
687
548
  @appinstance = ZuoraConnect::AppInstance.find_by(:id => values[:appinstance].to_i)
688
- ZuoraConnect::ZuoraUser.current_user_id = 0
689
549
  if @appinstance.blank?
690
550
  Apartment::Tenant.switch!("public")
691
551
  begin