zuora_connect 2.0.60h → 2.0.60
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/app/controllers/zuora_connect/static_controller.rb +12 -83
- data/app/models/zuora_connect/app_instance_base.rb +5 -9
- data/config/initializers/postgresql_adapter.rb +1 -34
- data/config/initializers/prometheus.rb +23 -78
- data/config/initializers/resque.rb +0 -14
- data/config/initializers/unicorn.rb +1 -29
- data/config/routes.rb +0 -5
- data/lib/middleware/json_parse_errors.rb +2 -13
- data/lib/middleware/metrics_middleware.rb +31 -45
- data/lib/resque/dynamic_queues.rb +1 -1
- data/lib/zuora_connect/controllers/helpers.rb +72 -205
- data/lib/zuora_connect/railtie.rb +5 -24
- data/lib/zuora_connect/version.rb +1 -1
- metadata +29 -29
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bae96287832facbb0f512eedca7038f2bd566650d4e057f0d623613cb3acb559
|
|
4
|
+
data.tar.gz: d3b1f756842c3231a23719669d81c7aa206dfc677ae19ae2e537d3c3f6c089ae
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 872a07f80dfbe1c12428cacc4369fe83a0f59eb20d953c0c43f609d19cd75556138e1162f4e175c6fdf10844f4bf2a01c0f8f1529c7a6e0774d7b53b47f4e68a
|
|
7
|
+
data.tar.gz: c2f5653b77bbc93521c37062542d12697fb21e055cff18a55846837e6f454dd2ce15963580f6623e523d6b30f677bce8e1fb7820a28b981cfa69c73bd6f7333a
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
module ZuoraConnect
|
|
2
2
|
class StaticController < ApplicationController
|
|
3
|
-
before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app
|
|
4
|
-
before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app
|
|
5
|
-
after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app
|
|
6
|
-
|
|
7
|
-
skip_before_action :verify_authenticity_token, :only => [:initialize_app
|
|
8
|
-
http_basic_authenticate_with name: ENV['PROVISION_USER'], password: ENV['PROVISION_SECRET'], :only => [:provision, :instance_user]
|
|
3
|
+
before_action :authenticate_connect_app_request, :except => [:metrics, :health, :initialize_app]
|
|
4
|
+
before_action :clear_connect_app_session, :only => [:metrics, :health, :initialize_app]
|
|
5
|
+
after_action :persist_connect_app_session, :except => [:metrics, :health, :initialize_app]
|
|
6
|
+
|
|
7
|
+
skip_before_action :verify_authenticity_token, :only => [:initialize_app]
|
|
9
8
|
|
|
10
9
|
def metrics
|
|
11
10
|
type = params[:type].present? ? params[:type] : "versions"
|
|
@@ -14,11 +13,11 @@ module ZuoraConnect
|
|
|
14
13
|
|
|
15
14
|
def health
|
|
16
15
|
if params[:error].present?
|
|
17
|
-
begin
|
|
16
|
+
begin
|
|
18
17
|
raise ZuoraConnect::Exceptions::Error.new('This is an error')
|
|
19
18
|
rescue => ex
|
|
20
19
|
case params[:error]
|
|
21
|
-
when 'Log'
|
|
20
|
+
when 'Log'
|
|
22
21
|
Rails.logger.error("Error in Health", ex)
|
|
23
22
|
when 'Exception'
|
|
24
23
|
raise
|
|
@@ -35,13 +34,11 @@ module ZuoraConnect
|
|
|
35
34
|
def initialize_app
|
|
36
35
|
begin
|
|
37
36
|
authenticate_connect_app_request
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}, status: 200
|
|
44
|
-
end
|
|
37
|
+
@appinstance.new_session(:session => @appinstance.data_lookup(:session => session))
|
|
38
|
+
render json: {
|
|
39
|
+
message: "Success",
|
|
40
|
+
status: 200
|
|
41
|
+
}, status: 200
|
|
45
42
|
rescue => ex
|
|
46
43
|
Rails.logger.error("Failed to Initialize application", ex)
|
|
47
44
|
if performed?
|
|
@@ -55,74 +52,6 @@ module ZuoraConnect
|
|
|
55
52
|
end
|
|
56
53
|
end
|
|
57
54
|
|
|
58
|
-
def provision
|
|
59
|
-
create_new_instance
|
|
60
|
-
unless performed?
|
|
61
|
-
render json: {
|
|
62
|
-
status: 200,
|
|
63
|
-
message: 'Success',
|
|
64
|
-
app_instance_id: @appinstance.id
|
|
65
|
-
}, status: 200
|
|
66
|
-
end
|
|
67
|
-
rescue StandardError => e
|
|
68
|
-
message = 'Failed to provision new instance'
|
|
69
|
-
if performed?
|
|
70
|
-
Rails.logger.error("#{message}: #{performed?}", e)
|
|
71
|
-
else
|
|
72
|
-
Rails.logger.error(message, e)
|
|
73
|
-
render json: {
|
|
74
|
-
status: 500,
|
|
75
|
-
message: message
|
|
76
|
-
}, status: 500
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def instance_user
|
|
81
|
-
ZuoraConnect::AppInstance.read_master_db do
|
|
82
|
-
ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
|
|
83
|
-
Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
|
|
84
|
-
|
|
85
|
-
if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
|
|
86
|
-
ElasticAPM.set_label(:trace_id, request.uuid)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
unless params[:id].present?
|
|
90
|
-
render json: {
|
|
91
|
-
status: 400,
|
|
92
|
-
message: 'No app instance id provided'
|
|
93
|
-
}, status: :bad_request
|
|
94
|
-
return
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
@appinstance = ZuoraConnect::AppInstance.find(params[:id]).new_session
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
zuora_client = @appinstance.send(ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION).client
|
|
101
|
-
client_describe, = zuora_client.rest_call(
|
|
102
|
-
url: zuora_client.rest_endpoint('genesis/user/info').gsub('v1/', ''),
|
|
103
|
-
session_type: zuora_client.class == ZuoraAPI::Oauth ? :bearer : :basic
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
render json: {
|
|
107
|
-
status: 200,
|
|
108
|
-
message: 'Success',
|
|
109
|
-
user_id: client_describe['coreUserId'],
|
|
110
|
-
username: client_describe['username'],
|
|
111
|
-
email: client_describe['workEmail']
|
|
112
|
-
}, status: 200
|
|
113
|
-
rescue ActiveRecord::RecordNotFound
|
|
114
|
-
render json: {
|
|
115
|
-
status: 400,
|
|
116
|
-
message: 'No app instance found'
|
|
117
|
-
}, status: :bad_request
|
|
118
|
-
rescue StandardError => e
|
|
119
|
-
Rails.logger.error('Error occurred getting user details', e)
|
|
120
|
-
render json: {
|
|
121
|
-
status: 500,
|
|
122
|
-
message: 'Failed to get user details'
|
|
123
|
-
}, status: 500
|
|
124
|
-
end
|
|
125
|
-
|
|
126
55
|
private
|
|
127
56
|
|
|
128
57
|
def clear_connect_app_session
|
|
@@ -338,10 +338,6 @@ module ZuoraConnect
|
|
|
338
338
|
raise
|
|
339
339
|
end
|
|
340
340
|
|
|
341
|
-
def aws_secrets
|
|
342
|
-
(Rails.application.secrets.aws || {}).transform_keys { |key| key.to_s }
|
|
343
|
-
end
|
|
344
|
-
|
|
345
341
|
#### START KMS ENCRYPTION Methods ####
|
|
346
342
|
def zuora_logins=(val)
|
|
347
343
|
write_attribute(:zuora_logins, kms_encrypt(val.to_json))
|
|
@@ -354,7 +350,7 @@ module ZuoraConnect
|
|
|
354
350
|
|
|
355
351
|
def kms_decrypt(value)
|
|
356
352
|
kms_tries ||= 0
|
|
357
|
-
kms_client = Aws::KMS::Client.new({region:
|
|
353
|
+
kms_client = Aws::KMS::Client.new({region: Rails.application.secrets.aws['AWS_REGION'], credentials: self.aws_auth_client}.delete_if { |k, v| v.blank? })
|
|
358
354
|
resp = kms_client.decrypt({ciphertext_blob: [value].pack("H*") })
|
|
359
355
|
return resp.plaintext
|
|
360
356
|
rescue *AWS_AUTH_ERRORS => ex
|
|
@@ -369,7 +365,7 @@ module ZuoraConnect
|
|
|
369
365
|
|
|
370
366
|
def kms_encrypt(value)
|
|
371
367
|
kms_tries ||= 0
|
|
372
|
-
kms_client = Aws::KMS::Client.new({region:
|
|
368
|
+
kms_client = Aws::KMS::Client.new({region: Rails.application.secrets.aws['AWS_REGION'], credentials: self.aws_auth_client}.delete_if {|k,v| v.blank? })
|
|
373
369
|
|
|
374
370
|
resp = kms_client.encrypt({key_id: kms_key, plaintext: value})
|
|
375
371
|
return resp.ciphertext_blob.unpack('H*').first
|
|
@@ -384,12 +380,12 @@ module ZuoraConnect
|
|
|
384
380
|
end
|
|
385
381
|
|
|
386
382
|
def kms_key
|
|
387
|
-
return ENV['AWS_KMS_ARN'] ||
|
|
383
|
+
return ENV['AWS_KMS_ARN'] || Rails.application.secrets.dig(:aws,'AWS_KMS_ARN')
|
|
388
384
|
end
|
|
389
385
|
|
|
390
386
|
def aws_auth_client
|
|
391
387
|
if Rails.env.to_s == 'development'
|
|
392
|
-
return Aws::Credentials.new(
|
|
388
|
+
return Aws::Credentials.new(Rails.application.secrets.aws['AWS_ACCESS_KEY_ID'], Rails.application.secrets.aws['AWS_SECRET_ACCESS_KEY'])
|
|
393
389
|
else
|
|
394
390
|
return nil
|
|
395
391
|
end
|
|
@@ -406,7 +402,7 @@ module ZuoraConnect
|
|
|
406
402
|
end
|
|
407
403
|
|
|
408
404
|
def self.write_to_telegraf(*args)
|
|
409
|
-
if ZuoraConnect.configuration.enable_metrics
|
|
405
|
+
if ZuoraConnect.configuration.enable_metrics
|
|
410
406
|
@@telegraf_host = ZuoraConnect::Telegraf.new() if @@telegraf_host == nil
|
|
411
407
|
unicorn_stats = self.unicorn_listener_stats() if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
|
412
408
|
@@telegraf_host.write(direction: 'Raindrops', tags: {}, values: unicorn_stats) unless unicorn_stats.blank?
|
|
@@ -2,33 +2,7 @@ module ActiveRecord
|
|
|
2
2
|
module ConnectionAdapters
|
|
3
3
|
class PostgreSQLAdapter < AbstractAdapter
|
|
4
4
|
private
|
|
5
|
-
def
|
|
6
|
-
initializer = OID::TypeMapInitializer.new(type_map)
|
|
7
|
-
if supports_ranges?
|
|
8
|
-
query = <<-SQL
|
|
9
|
-
SELECT DISTINCT on (t.typname) t.oid, t.typname, t.typelem, t.typdelim, t.typinput, r.rngsubtype, t.typtype, t.typbasetype
|
|
10
|
-
FROM pg_type as t
|
|
11
|
-
LEFT JOIN pg_range as r ON oid = rngtypid
|
|
12
|
-
SQL
|
|
13
|
-
else
|
|
14
|
-
query = <<-SQL
|
|
15
|
-
SELECT DISTINCT on (t.typname) t.oid, t.typname, t.typelem, t.typdelim, t.typinput, t.typtype, t.typbasetype
|
|
16
|
-
FROM pg_type as t
|
|
17
|
-
SQL
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
if oids
|
|
21
|
-
query += "WHERE t.oid::integer IN (%s)" % oids.join(", ")
|
|
22
|
-
else
|
|
23
|
-
query += initializer.query_conditions_for_initial_load
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
execute_and_clear(query, "SCHEMA", []) do |records|
|
|
27
|
-
initializer.run(records)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def load_additional_types_deprecated(type_map, oids = nil)
|
|
5
|
+
def load_additional_types(type_map, oids = nil)
|
|
32
6
|
initializer = OID::TypeMapInitializer.new(type_map)
|
|
33
7
|
if supports_ranges?
|
|
34
8
|
query = <<-SQL
|
|
@@ -53,13 +27,6 @@ module ActiveRecord
|
|
|
53
27
|
initializer.run(records)
|
|
54
28
|
end
|
|
55
29
|
end
|
|
56
|
-
|
|
57
|
-
rails_version = Rails.version.split('.').map { |x| x.to_i }
|
|
58
|
-
if (rails_version <=> [5, 2, 0]) >= 1
|
|
59
|
-
alias :load_additional_types :load_additional_types_latest
|
|
60
|
-
else
|
|
61
|
-
alias :load_additional_types :load_additional_types_deprecated
|
|
62
|
-
end
|
|
63
30
|
end
|
|
64
31
|
end
|
|
65
32
|
end
|
|
@@ -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.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 =
|
|
51
|
-
CONNECT_VERSION =
|
|
52
|
-
RAILS_VERSION =
|
|
53
|
-
RUBY_V =
|
|
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
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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 =
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
-
|
|
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
|
data/config/routes.rb
CHANGED
|
@@ -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
|
|
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
|
|
@@ -124,15 +124,10 @@ 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
|
-
end
|
|
136
131
|
ZuoraConnect.logger.error(ex) if !ZuoraConnect::AppInstance::IGNORED_LOCALS.include?(ex.locale.to_s.downcase)
|
|
137
132
|
end
|
|
138
133
|
begin
|
|
@@ -224,80 +219,6 @@ module ZuoraConnect
|
|
|
224
219
|
return (request.headers['ZuoraCurrentEntity'].present? || cookies['ZuoraCurrentEntity'].present?)
|
|
225
220
|
end
|
|
226
221
|
|
|
227
|
-
def create_new_instance
|
|
228
|
-
ZuoraConnect::AppInstance.read_master_db do
|
|
229
|
-
Thread.current[:appinstance] = nil
|
|
230
|
-
ZuoraConnect.logger.with_fields = {} if ZuoraConnect.logger.is_a?(Ougai::Logger)
|
|
231
|
-
Rails.logger.with_fields = {} if Rails.logger.is_a?(Ougai::Logger)
|
|
232
|
-
|
|
233
|
-
if defined?(ElasticAPM) && ElasticAPM.running? && ElasticAPM.respond_to?(:set_label)
|
|
234
|
-
ElasticAPM.set_label(:trace_id, request.uuid)
|
|
235
|
-
end
|
|
236
|
-
|
|
237
|
-
zuora_host = request.headers['zuora-host']
|
|
238
|
-
zuora_entity_id = (request.headers['zuora-entity-ids'] || '').gsub(
|
|
239
|
-
'-',
|
|
240
|
-
''
|
|
241
|
-
).split(',').first
|
|
242
|
-
|
|
243
|
-
# Validate host present
|
|
244
|
-
if zuora_host.blank?
|
|
245
|
-
render json: {
|
|
246
|
-
status: 401,
|
|
247
|
-
message: 'zuora-host header was not supplied.'
|
|
248
|
-
}, status: :unauthorized
|
|
249
|
-
return
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
# Validate entity-ids present
|
|
253
|
-
if zuora_entity_id.blank?
|
|
254
|
-
render json: {
|
|
255
|
-
status: 401,
|
|
256
|
-
message: 'zuora-entity-ids header was not supplied.'
|
|
257
|
-
}, status: :unauthorized
|
|
258
|
-
return
|
|
259
|
-
end
|
|
260
|
-
|
|
261
|
-
rest_domain = ZuoraAPI::Login.new(url: "https://#{zuora_host}").rest_domain
|
|
262
|
-
app_instance_id = ZuoraConnect::AppInstance.where(
|
|
263
|
-
'zuora_entity_ids ?& array[:entities] AND zuora_domain = :host',
|
|
264
|
-
entities: [zuora_entity_id],
|
|
265
|
-
host: rest_domain
|
|
266
|
-
).pluck(:id).first
|
|
267
|
-
|
|
268
|
-
if app_instance_id.present?
|
|
269
|
-
render json: {
|
|
270
|
-
status: 409,
|
|
271
|
-
message: 'Instance already exists.',
|
|
272
|
-
app_instance_id: app_instance_id
|
|
273
|
-
}, status: 409
|
|
274
|
-
else
|
|
275
|
-
Apartment::Tenant.switch!("public")
|
|
276
|
-
retry_count = 3
|
|
277
|
-
begin
|
|
278
|
-
@appinstance = new_instance(
|
|
279
|
-
next_instance_id,
|
|
280
|
-
zuora_entity_id,
|
|
281
|
-
rest_domain,
|
|
282
|
-
retry_count: retry_count
|
|
283
|
-
)
|
|
284
|
-
rescue ActiveRecord::RecordNotUnique
|
|
285
|
-
retry if (retry_count -= 1).positive?
|
|
286
|
-
return
|
|
287
|
-
end
|
|
288
|
-
|
|
289
|
-
app_instance_id = @appinstance.id
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
begin
|
|
293
|
-
Apartment::Tenant.switch!('public')
|
|
294
|
-
Apartment::Tenant.create(app_instance_id.to_s)
|
|
295
|
-
rescue Apartment::TenantExists
|
|
296
|
-
ZuoraConnect.logger.debug('Tenant Already Exists')
|
|
297
|
-
end
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
|
|
301
222
|
private
|
|
302
223
|
def setup_instance_via_prod_mode
|
|
303
224
|
zuora_entity_id = request.headers['ZuoraCurrentEntity'] || cookies['ZuoraCurrentEntity']
|
|
@@ -305,7 +226,7 @@ module ZuoraConnect
|
|
|
305
226
|
if zuora_entity_id.present?
|
|
306
227
|
zuora_tenant_id = cookies['Zuora-Tenant-Id']
|
|
307
228
|
zuora_user_id = cookies['Zuora-User-Id']
|
|
308
|
-
zuora_host = request.headers[
|
|
229
|
+
zuora_host = request.headers["HTTP_X_FORWARDED_HOST"] || "apisandbox.zuora.com"
|
|
309
230
|
|
|
310
231
|
zuora_details = {'host' => zuora_host, 'user_id' => zuora_user_id, 'tenant_id' => zuora_tenant_id, 'entity_id' => zuora_entity_id}
|
|
311
232
|
auth_headers = {}
|
|
@@ -407,16 +328,13 @@ module ZuoraConnect
|
|
|
407
328
|
|
|
408
329
|
zuora_user_id = cookies['Zuora-User-Id'] || session["ZuoraCurrentIdentity"]['userId']
|
|
409
330
|
|
|
331
|
+
#One deployed instance
|
|
410
332
|
if appinstances.size == 1
|
|
411
333
|
ZuoraConnect.logger.debug("Instance is #{appinstances.to_h.keys.first}")
|
|
412
334
|
@appinstance = ZuoraConnect::AppInstance.find(appinstances.to_h.keys.first)
|
|
413
|
-
end
|
|
414
335
|
|
|
415
|
-
# One deployed instance with credentials
|
|
416
|
-
if defined?(@appinstance) && !@appinstance['zuora_logins'].nil?
|
|
417
336
|
#Add user/update
|
|
418
337
|
begin
|
|
419
|
-
ZuoraConnect::ZuoraUser.reset_table_name
|
|
420
338
|
@zuora_user = ZuoraConnect::ZuoraUser.where(:zuora_user_id => zuora_user_id).first
|
|
421
339
|
rescue ActiveRecord::StatementInvalid => ex
|
|
422
340
|
if ex.message.include?("PG::UndefinedTable") && ex.message.include?("zuora_users")
|
|
@@ -440,8 +358,7 @@ module ZuoraConnect
|
|
|
440
358
|
session["#{@appinstance.id}::user::localUserId"] = @zuora_user.id
|
|
441
359
|
session["#{@appinstance.id}::user::email"] = session['ZuoraCurrentIdentity']["username"]
|
|
442
360
|
session["#{@appinstance.id}::user::timezone"] = session['ZuoraCurrentIdentity']["timeZone"]
|
|
443
|
-
session["#{@appinstance.id}::user::
|
|
444
|
-
session["#{@appinstance.id}::user::locale"] = session['ZuoraCurrentIdentity']["locale"]
|
|
361
|
+
session["#{@appinstance.id}::user::locale"] = session['ZuoraCurrentIdentity']["language"]
|
|
445
362
|
session["appInstance"] = @appinstance.id
|
|
446
363
|
|
|
447
364
|
#We have multiple, user must pick
|
|
@@ -463,85 +380,79 @@ module ZuoraConnect
|
|
|
463
380
|
return
|
|
464
381
|
end
|
|
465
382
|
Apartment::Tenant.switch!("public")
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
ActiveRecord::Base.transaction do
|
|
470
|
-
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)
|
|
471
386
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
|
|
477
|
-
return
|
|
478
|
-
end
|
|
479
|
-
end
|
|
387
|
+
if appinstances.size > 0
|
|
388
|
+
redirect_to "https://#{zuora_host}/apps/newlogin.do?retURL=#{request.fullpath}"
|
|
389
|
+
return
|
|
390
|
+
end
|
|
480
391
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
)
|
|
501
|
-
|
|
502
|
-
new_zuora_client = ZuoraAPI::Oauth.new(url: "https://#{zuora_host}", oauth_client_id: oauth_response["clientId"], oauth_secret: oauth_response["clientSecret"] )
|
|
503
|
-
if session["ZuoraCurrentUserInfo"].blank?
|
|
504
|
-
client_describe, response = new_zuora_client.rest_call(url: zuora_client.rest_endpoint("genesis/user/info").gsub('v1/', ''), session_type: :bearer)
|
|
505
|
-
else
|
|
506
|
-
client_describe = session["ZuoraCurrentUserInfo"]
|
|
507
|
-
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
|
+
)
|
|
508
411
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
ZuoraConnect::AppInstance::LOGIN_TENANT_DESTINATION => {
|
|
516
|
-
"tenant_type": "Zuora",
|
|
517
|
-
"username": session["ZuoraCurrentIdentity"]["username"],
|
|
518
|
-
"url": new_zuora_client.url,
|
|
519
|
-
"status": "Active",
|
|
520
|
-
"oauth_client_id": oauth_response['clientId'],
|
|
521
|
-
"oauth_secret": oauth_response['clientSecret'],
|
|
522
|
-
"authentication_type": "OAUTH",
|
|
523
|
-
"entities": available_entities.map {|e| e.merge({'displayName' => client_describe["tenantName"]})}
|
|
524
|
-
},
|
|
525
|
-
"tenant_ids": available_entities.map{|e| e['entityId']}.uniq,
|
|
526
|
-
}
|
|
527
|
-
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
|
|
528
418
|
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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
|
|
532
446
|
else
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
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
|
|
540
454
|
end
|
|
541
455
|
end
|
|
542
|
-
rescue ActiveRecord::RecordNotUnique
|
|
543
|
-
retry if (retry_count -= 1).positive?
|
|
544
|
-
return
|
|
545
456
|
end
|
|
546
457
|
|
|
547
458
|
Apartment::Tenant.switch!("public")
|
|
@@ -572,8 +483,8 @@ module ZuoraConnect
|
|
|
572
483
|
|
|
573
484
|
rescue ZuoraAPI::Exceptions::ZuoraAPIError, Exception => ex
|
|
574
485
|
if ex.message.include?("Referenced User resource(s) not found") && ex.class == ZuoraAPI::Exceptions::ZuoraAPIError
|
|
575
|
-
locals = {title: "Provisioning Error", message: "New
|
|
576
|
-
render "zuora_connect/static/error_handled", locals: locals, status:
|
|
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
|
|
577
488
|
else
|
|
578
489
|
session.clear
|
|
579
490
|
if defined?(ex.response) && ex.response.present? && defined?(ex.response.body)
|
|
@@ -629,50 +540,6 @@ module ZuoraConnect
|
|
|
629
540
|
end
|
|
630
541
|
end
|
|
631
542
|
|
|
632
|
-
def next_instance_id
|
|
633
|
-
min_instance_id = 24_999_999
|
|
634
|
-
(ZuoraConnect::AppInstance.all.where("id > #{min_instance_id}").order(id: :desc).limit(1).pluck(:id).first || min_instance_id) + 1
|
|
635
|
-
end
|
|
636
|
-
|
|
637
|
-
def new_instance(id, zuora_entity_id, rest_domain, task_data: nil, retry_count: 0)
|
|
638
|
-
app_instance = ZuoraConnect::AppInstance.new(
|
|
639
|
-
:id => id,
|
|
640
|
-
:api_token => generate_token,
|
|
641
|
-
:token => generate_token,
|
|
642
|
-
:oauth_expires_at => Time.now + 1000.years,
|
|
643
|
-
:zuora_domain => rest_domain,
|
|
644
|
-
:zuora_entity_ids => [zuora_entity_id]
|
|
645
|
-
)
|
|
646
|
-
|
|
647
|
-
if task_data.nil?
|
|
648
|
-
# no encryption
|
|
649
|
-
app_instance['zuora_logins'] = task_data
|
|
650
|
-
else
|
|
651
|
-
# kms encrypt
|
|
652
|
-
app_instance.zuora_logins = task_data
|
|
653
|
-
end
|
|
654
|
-
|
|
655
|
-
begin
|
|
656
|
-
app_instance.save(:validate => false)
|
|
657
|
-
rescue ActiveRecord::RecordNotUnique
|
|
658
|
-
raise if retry_count > 1
|
|
659
|
-
|
|
660
|
-
Thread.current[:appinstance] = nil
|
|
661
|
-
session['appInstance'] = nil
|
|
662
|
-
render 'zuora_connect/static/error_handled', :locals => {
|
|
663
|
-
:title => 'Application could not create unique tokens.',
|
|
664
|
-
:message => 'Please contact support or retry launching application.'
|
|
665
|
-
}, :layout => false
|
|
666
|
-
return
|
|
667
|
-
end
|
|
668
|
-
|
|
669
|
-
app_instance
|
|
670
|
-
end
|
|
671
|
-
|
|
672
|
-
def generate_token
|
|
673
|
-
rand(36**64).to_s(36)
|
|
674
|
-
end
|
|
675
|
-
|
|
676
543
|
def setup_instance_via_dev_mode
|
|
677
544
|
session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
|
|
678
545
|
user = ZuoraConnect.configuration.dev_mode_user
|
|
@@ -28,6 +28,11 @@ module ZuoraConnect
|
|
|
28
28
|
::Rails.configuration.action_dispatch.x_sendfile_header = nil
|
|
29
29
|
end
|
|
30
30
|
|
|
31
|
+
if defined? Prometheus
|
|
32
|
+
initializer "prometheus.configure_rails_initialization" do |app|
|
|
33
|
+
app.middleware.use Prometheus::Middleware::Exporter,(options ={:path => '/connect/internal/metrics'})
|
|
34
|
+
end
|
|
35
|
+
end
|
|
31
36
|
initializer "zuora_connect.configure_rails_initialization" do |app|
|
|
32
37
|
app.middleware.insert_after Rack::Sendfile, ZuoraConnect::MetricsMiddleware
|
|
33
38
|
app.middleware.insert_after ActionDispatch::RequestId, ZuoraConnect::RequestIdMiddleware
|
|
@@ -35,15 +40,6 @@ module ZuoraConnect
|
|
|
35
40
|
app.config.middleware.use ZuoraConnect::JsonParseErrors
|
|
36
41
|
end
|
|
37
42
|
|
|
38
|
-
if defined? Prometheus
|
|
39
|
-
require 'rack'
|
|
40
|
-
require 'prometheus/middleware/exporter'
|
|
41
|
-
initializer "prometheus.configure_rails_initialization" do |app|
|
|
42
|
-
app.middleware.insert_after ZuoraConnect::MetricsMiddleware, Prometheus::Middleware::Exporter, path: '/connect/internal/metrics'
|
|
43
|
-
app.config.middleware.use Rack::Deflater, if: ->(env, *) { env['PATH_INFO'] == '/connect/internal/metrics' }
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
43
|
# hook to process_action
|
|
48
44
|
ActiveSupport::Notifications.subscribe('process_action.action_controller', ZuoraConnect::PageRequest.new)
|
|
49
45
|
|
|
@@ -81,21 +77,6 @@ module ZuoraConnect
|
|
|
81
77
|
request_headers =
|
|
82
78
|
event.payload[:headers].env.
|
|
83
79
|
reject { |key| key.to_s.include?('.') || REQUEST_HEADERS_TO_IGNORE.include?(key.to_s) }
|
|
84
|
-
begin
|
|
85
|
-
if request_headers["HTTP_AUTHORIZATION"].present?
|
|
86
|
-
if request_headers["HTTP_AUTHORIZATION"].include?("Basic")
|
|
87
|
-
user_password = request_headers["HTTP_AUTHORIZATION"].split("Basic").last.strip
|
|
88
|
-
user, password = Base64.decode64(user_password).split(":")
|
|
89
|
-
request_headers["HTTP_AUTHORIZATION"] = "Basic #{user}:ValueFiltered"
|
|
90
|
-
elsif
|
|
91
|
-
request_headers["HTTP_AUTHORIZATION"] = "ValueFiltered"
|
|
92
|
-
end
|
|
93
|
-
end
|
|
94
|
-
request_headers["HTTP_API_TOKEN"] = "ValueFiltered" if request_headers["HTTP_API_TOKEN"].present?
|
|
95
|
-
rescue
|
|
96
|
-
request_headers.delete("HTTP_API_TOKEN")
|
|
97
|
-
request_headers.delete("HTTP_AUTHORIZATION")
|
|
98
|
-
end
|
|
99
80
|
items.merge!({ headers: request_headers.to_s })
|
|
100
81
|
end
|
|
101
82
|
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: zuora_connect
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.0.
|
|
4
|
+
version: 2.0.60
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Connect Team
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2020-
|
|
11
|
+
date: 2020-07-02 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: apartment
|
|
@@ -429,53 +429,53 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
429
429
|
version: '0'
|
|
430
430
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
431
431
|
requirements:
|
|
432
|
-
- - "
|
|
432
|
+
- - ">="
|
|
433
433
|
- !ruby/object:Gem::Version
|
|
434
|
-
version:
|
|
434
|
+
version: '0'
|
|
435
435
|
requirements: []
|
|
436
436
|
rubygems_version: 3.0.3
|
|
437
437
|
signing_key:
|
|
438
438
|
specification_version: 4
|
|
439
439
|
summary: Summary of Connect.
|
|
440
440
|
test_files:
|
|
441
|
-
- test/fixtures/zuora_connect/app_instances.yml
|
|
442
|
-
- test/models/zuora_connect/app_instance_test.rb
|
|
443
441
|
- test/integration/navigation_test.rb
|
|
444
442
|
- test/controllers/zuora_connect/api/v1/app_instance_controller_test.rb
|
|
445
|
-
- test/
|
|
443
|
+
- test/fixtures/zuora_connect/app_instances.yml
|
|
446
444
|
- test/lib/generators/zuora_connect/datatable_generator_test.rb
|
|
447
|
-
- test/
|
|
448
|
-
- test/
|
|
449
|
-
- test/dummy/public/favicon.ico
|
|
450
|
-
- test/dummy/public/422.html
|
|
445
|
+
- test/models/zuora_connect/app_instance_test.rb
|
|
446
|
+
- test/zuora_connect_test.rb
|
|
451
447
|
- test/dummy/Rakefile
|
|
452
448
|
- test/dummy/config.ru
|
|
449
|
+
- test/dummy/public/422.html
|
|
450
|
+
- test/dummy/public/404.html
|
|
451
|
+
- test/dummy/public/500.html
|
|
452
|
+
- test/dummy/public/favicon.ico
|
|
453
|
+
- test/dummy/app/controllers/application_controller.rb
|
|
454
|
+
- test/dummy/app/helpers/application_helper.rb
|
|
455
|
+
- test/dummy/app/views/layouts/application.html.erb
|
|
456
|
+
- test/dummy/app/assets/javascripts/application.js
|
|
457
|
+
- test/dummy/app/assets/stylesheets/application.css
|
|
458
|
+
- test/dummy/README.rdoc
|
|
459
|
+
- test/dummy/bin/rails
|
|
460
|
+
- test/dummy/bin/rake
|
|
461
|
+
- test/dummy/bin/bundle
|
|
462
|
+
- test/dummy/bin/setup
|
|
453
463
|
- test/dummy/config/secrets.yml
|
|
454
464
|
- test/dummy/config/boot.rb
|
|
455
|
-
- test/dummy/config/
|
|
465
|
+
- test/dummy/config/initializers/mime_types.rb
|
|
466
|
+
- test/dummy/config/initializers/filter_parameter_logging.rb
|
|
456
467
|
- test/dummy/config/initializers/session_store.rb
|
|
468
|
+
- test/dummy/config/initializers/inflections.rb
|
|
469
|
+
- test/dummy/config/initializers/cookies_serializer.rb
|
|
457
470
|
- test/dummy/config/initializers/assets.rb
|
|
458
471
|
- test/dummy/config/initializers/wrap_parameters.rb
|
|
459
|
-
- test/dummy/config/initializers/filter_parameter_logging.rb
|
|
460
472
|
- test/dummy/config/initializers/backtrace_silencers.rb
|
|
461
|
-
- test/dummy/config/initializers/mime_types.rb
|
|
462
|
-
- test/dummy/config/initializers/inflections.rb
|
|
463
|
-
- test/dummy/config/initializers/cookies_serializer.rb
|
|
464
|
-
- test/dummy/config/routes.rb
|
|
465
473
|
- test/dummy/config/database.yml
|
|
466
|
-
- test/dummy/config/
|
|
474
|
+
- test/dummy/config/environment.rb
|
|
475
|
+
- test/dummy/config/application.rb
|
|
476
|
+
- test/dummy/config/routes.rb
|
|
467
477
|
- test/dummy/config/environments/production.rb
|
|
468
478
|
- test/dummy/config/environments/development.rb
|
|
469
|
-
- test/dummy/config/
|
|
479
|
+
- test/dummy/config/environments/test.rb
|
|
470
480
|
- test/dummy/config/locales/en.yml
|
|
471
|
-
- test/dummy/README.rdoc
|
|
472
|
-
- test/dummy/bin/rake
|
|
473
|
-
- test/dummy/bin/setup
|
|
474
|
-
- test/dummy/bin/rails
|
|
475
|
-
- test/dummy/bin/bundle
|
|
476
|
-
- test/dummy/app/views/layouts/application.html.erb
|
|
477
|
-
- test/dummy/app/assets/javascripts/application.js
|
|
478
|
-
- test/dummy/app/assets/stylesheets/application.css
|
|
479
|
-
- test/dummy/app/helpers/application_helper.rb
|
|
480
|
-
- test/dummy/app/controllers/application_controller.rb
|
|
481
481
|
- test/test_helper.rb
|