zuora_connect 3.0.0.pre.m → 3.0.0.pre.r
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/MIT-LICENSE +1 -1
- data/README.md +219 -0
- data/app/models/zuora_connect/app_instance_base.rb +19 -6
- data/app/models/zuora_connect/telegraf.rb +73 -0
- data/app/models/zuora_connect/zuora_user.rb +32 -1
- data/config/initializers/unicorn.rb +1 -1
- data/config/initializers/zuora_observability.rb +21 -0
- data/lib/metrics/influx/point_value.rb +79 -0
- data/lib/metrics/net.rb +7 -7
- data/lib/middleware/metrics_middleware.rb +34 -3
- data/lib/zuora_connect.rb +2 -2
- data/lib/zuora_connect/configuration.rb +2 -2
- data/lib/zuora_connect/controllers/helpers.rb +13 -31
- data/lib/zuora_connect/railtie.rb +3 -0
- data/lib/zuora_connect/version.rb +1 -1
- metadata +56 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8b3516f74913531168adf62cf95a28fe805018ab49ec723c9083d8f80064c158
|
4
|
+
data.tar.gz: 78e7f843dcfdd421d3dd80eb868afba810c68f6b85783a5efb645f93bf3c6097
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e6760f6ae414ea0362a93f4ed28d6345d3cf2247e9bac4bcb4e927159da124507fb342ba3a8237176885aa9a8d1fd389a8c629c1cedf97914d6d48757e9d95b0
|
7
|
+
data.tar.gz: 7b92aebfc8426957e86dec98a6f8251e124094deee5b55776e65c6e5bd2d3d6615bc08740d9658766d7164d10d4193f8591d096702a2c605c4426d2c07cf4f53
|
data/MIT-LICENSE
CHANGED
data/README.md
ADDED
@@ -0,0 +1,219 @@
|
|
1
|
+
# Connect Gem
|
2
|
+
|
3
|
+
[![Gem Version](https://badge.fury.io/rb/zuora_connect.svg)](https://badge.fury.io/rb/zuora_connect)
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
This gem requires a postgres database
|
7
|
+
|
8
|
+
## Install
|
9
|
+
|
10
|
+
Add this line to your application's Gemfile:
|
11
|
+
|
12
|
+
```ruby
|
13
|
+
gem 'zuora_connect'
|
14
|
+
```
|
15
|
+
|
16
|
+
Then execute `bundle install` in your terminal
|
17
|
+
|
18
|
+
## How to contribute to this repository
|
19
|
+
https://confluence.zuora.com/pages/viewpage.action?spaceKey=ZCP&title=Pushing+to+GIT
|
20
|
+
|
21
|
+
## Configuration
|
22
|
+
|
23
|
+
### Settings
|
24
|
+
This gem can be configured by adding `connect.rb` to the `config/initializers` folder. An example file and the available options can be seen below.
|
25
|
+
```ruby
|
26
|
+
ZuoraConnect.configure do |config|
|
27
|
+
config.url = ""
|
28
|
+
config.delayed_job = false
|
29
|
+
config.default_time_zone = Time.zone
|
30
|
+
config.default_locale = :en
|
31
|
+
config.timeout = 5.minutes
|
32
|
+
config.private_key = ""
|
33
|
+
config.mode = "Production"
|
34
|
+
config.dev_mode_logins = { "target_login" => {"tenant_type" => "Zuora", "username" => "user", "password" => "pass", "url" => "url"} }
|
35
|
+
config.dev_mode_options = {"name" => {"config_name" => "name", "datatype" => "type", "value" => "value"}}
|
36
|
+
config.dev_mode_mode = "Universal"
|
37
|
+
end
|
38
|
+
```
|
39
|
+
|
40
|
+
| Option | Description | Required | Values | Default | Example |
|
41
|
+
| -------------------- | ----------------------------------------------------------- | -------- | -------------------------------------------------------------------------------------- | --------------------------- | ------------------------------------------ |
|
42
|
+
| url | URL for the gem to connect to | Optional | https://connect.zuora.com <br/> https://connect-staging.zuora.com <br/> localhost:3000 | "https://connect.zuora.com" | config.url = `"https://connect.zuora.com"` |
|
43
|
+
| delayed_job | Used to indicate if Delayed Job is used by this Application | Optional | true or false | `true`| `config.delayed_job - true`|
|
44
|
+
| default_time_zone | Used to indicate the default timezone for the application | Optional | A valid time zone object | `Time.zone`| `config.default_time_zone = Time.zone` |
|
45
|
+
| default_locale | Used to indicate the default locale for the application | Optional | A valid locale| `:en`| `config.default_locale = :en`|
|
46
|
+
| private_key| Used to indicate the private key to use when decrypting the data payload|Required for Production| A valid private key| `nil`|`config.private_key = File.open(#{Rails.root/private_key})`|
|
47
|
+
| timeout|Used to indicate the amount of time the current session stays active before syncing with ZuoraConnect| Optional |ActiveSupport::Duration |`5.minutes`|`config.timeout = 1.hour`|
|
48
|
+
| mode|Used to indicate current environment the gem should run against|Optional |Production or Development|`"Production"`|`config.mode = "Development"`|
|
49
|
+
| dev_mode_appinstance|Used to indicate the schema name to use when in development mode|Optional|String|`"1"` |`config.dev_mode_appinstance = "1"`|
|
50
|
+
| dev_mode_admin|Used to indicate if admin mode should be turned on in development mode. This will cause all admin calls to be evaluated to true when displaying admin only elements in your application.|Optional|true or false|`false`|`config.dev_mode_admin = true`|
|
51
|
+
| dev_mode_pass|Used to mock up the users ZuoraConnect password|Optional |String|`"Test"`|`config.dev_mode_pass = "password1"`|
|
52
|
+
| dev_mode_user|Used to mock up the users ZuoraConnect username|Optional|String|`"Test"`|`config.dev_mode_user = "User1"`|
|
53
|
+
| dev_mode_logins|Used to mock up the login payload from ZuoraConnect|Optional|Hash|`nil`| `config.dev_mode_logins= { "target_login" => {"tenant_type" => "Zuora","username" => "user","password" => "pass","url" => "url"}}`
|
54
|
+
| dev_mode_mode|Used to mock up the mode passed from ZuoraConnect|Optional |String|`"Universal" `|`config.dev_mode_mode = "Mode2"`|
|
55
|
+
| dev_mode_options|Used to mock up the options payload from ZuoraConnect|Optional |Hash|`nil`|'config.dev_mode_options ={"name" => {"config_name" => "name","datatype" => "type","value" => "value"}}'|
|
56
|
+
|
57
|
+
|
58
|
+
### Controller Setup
|
59
|
+
The following controllers should have the below lines added to them
|
60
|
+
|
61
|
+
#### Application Controller ( `controllers/application_controller.rb`)
|
62
|
+
```ruby
|
63
|
+
before_action :authenticate_connect_app_request
|
64
|
+
after_action :persist_connect_app_session
|
65
|
+
```
|
66
|
+
|
67
|
+
#### Admin controllers
|
68
|
+
```ruby
|
69
|
+
before_action :check_connect_admin!
|
70
|
+
```
|
71
|
+
|
72
|
+
#### Admin actions inside a controllers
|
73
|
+
|
74
|
+
```ruby
|
75
|
+
before_action :check_connect_admin!, :only => [:logs]
|
76
|
+
```
|
77
|
+
#### API Controller
|
78
|
+
```ruby
|
79
|
+
before_action :authenticate_app_api_request
|
80
|
+
```
|
81
|
+
|
82
|
+
An explanation of the available before_filters and what they do can be found below
|
83
|
+
|
84
|
+
| Name | Description |
|
85
|
+
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
86
|
+
| authenticate_app_api_request | Authenticates the incoming request, handles data segmentation, and creates the @appinstance global variable |
|
87
|
+
| persist_connect_app_session | Saves the current user session for use after every request so that every request does not require authentication with Connect. Instead authentication to Connect is done based on the timeout value of the session set in the configuration steps above |
|
88
|
+
| check_connect_admin | Checks if the user is labeled as an admin as deemed by the encrypted request payload coming from Connect. This filter is used to lock down certain functionality that only the Developer should have access to. <br/> Returns false if the user is not an admin |
|
89
|
+
| check_connect_admin! | The filter works the same as the above but instead raises an exception `ZuoraConnect::Exceptions::AccessDenied` |
|
90
|
+
| authenticate_app_api_request | Authenticates the incoming API request based on the token passed in. The token must match a token associate to one of the available app instances. This token is stored on the app instance object as api_token. More information can be found in the API authentication section below. |
|
91
|
+
|
92
|
+
## Usage
|
93
|
+
|
94
|
+
The Connect gem provides an integration with ZuoraConnect by allowing the application to read data from Connect and make the appropriate API calls.
|
95
|
+
|
96
|
+
### Data Segmentation
|
97
|
+
|
98
|
+
The Connect Gem provides an integration with ZuoraConnect by allowing the application to read data from Connect and make the appropriate API calls.
|
99
|
+
|
100
|
+
### The App Instance object
|
101
|
+
|
102
|
+
#### Methods and Attributes
|
103
|
+
|
104
|
+
| Name | Type | Description | Example |
|
105
|
+
| ------------ | ----------- | ------------ | --------------------------- |
|
106
|
+
| new_session | `Method` | | @appinstance.new_sesion |
|
107
|
+
| updateOption | `Method` | | @appinstance.updateOption() |
|
108
|
+
| options | `Attribute` | | @appinstance.options |
|
109
|
+
| mode | `Attribute` | | @appinstance.mode |
|
110
|
+
| logins | `Attribute` | | @appinstance.logins |
|
111
|
+
| task_data | `Attribute` | | @appinstance.task_data |
|
112
|
+
| token | `Attribute` | `DEPRECATED` | @appinstance.token |
|
113
|
+
| api_token | `Attribute` | | @appinstance.api_token |
|
114
|
+
|
115
|
+
#### Accessing the Object
|
116
|
+
|
117
|
+
The `@appinstance` object is accessible in every View and Controller in your application. In order to access `@appinstance` in a Model it must be pulled out of the current thread by doing the following:
|
118
|
+
```ruby
|
119
|
+
@appinstance = Thread.current[:appinstance]
|
120
|
+
```
|
121
|
+
### Login Object
|
122
|
+
|
123
|
+
All Login information available to your app is passed from connect in a hash in the form `{:target_login => data, :source_login => data}`. It is important to note that target_login and source_login can be variable and that any number of logins can be passed to your application as defined by Connect. For example the following use case could exist: `{:zuora_login => data, :system1_login => data,:system2_login => data}`. This information can be retrieved by the @appinstance object through a call similiar to this `@appinstance.system2_login`. This removes the requirement of using `@appinstance.logins `and looping through the returned hash if you are aware of the logins that Connect will be sending your application.
|
124
|
+
|
125
|
+
Each login is mapped as a login object associated to the `@appinstance` object. Every attribute associated to this object passed from Connect is available on this object as an attribute. At a minimum the below attributes will be available
|
126
|
+
|
127
|
+
|
128
|
+
| Name | Description |
|
129
|
+
| ----------- | ------------------------------------------ |
|
130
|
+
| tenant_type | Login type such as "Zuora" or "Salesforce" |
|
131
|
+
| username | The username |
|
132
|
+
| password | The password |
|
133
|
+
| url | Endpoint or URL |
|
134
|
+
|
135
|
+
#### Zuora logins
|
136
|
+
The Connect Gem has built-in integration with the Zuora gem and automatically creates a ZuoraLogin object for every Zuora login. This can be accessed by executing something similiar to the following:
|
137
|
+
```ruby
|
138
|
+
@appinstance.target_login.client.rest_call
|
139
|
+
```
|
140
|
+
|
141
|
+
### Admin authentication
|
142
|
+
|
143
|
+
#### Controller
|
144
|
+
|
145
|
+
Authentication is done through a before filter. Reference the above section on controller setup
|
146
|
+
|
147
|
+
#### View
|
148
|
+
|
149
|
+
`is_app_admin?` is a view helper that returns true if the user is an admin
|
150
|
+
|
151
|
+
### API Authentication
|
152
|
+
|
153
|
+
In order to allow direct access to the application without Connect for API calls the :authenticate_app_api_request before filter must be used in your controller and both authenticate_connect_app_request and persist_connect_app_session filters should be skipped to avoid collision.
|
154
|
+
|
155
|
+
When making an API call to your application the token associated to the `@appinstance` object must be passed in as the password in a basic auth header with the username being the users Connect username or in the access_token param
|
156
|
+
|
157
|
+
## Rails Console
|
158
|
+
|
159
|
+
By Default all queries executed from Rails Console will filter against schemas that are named “Public” and your current system $user. You can verify this by executing `ActiveRecord::Base.connection.schema_search_path` in rails console which should return “”$user", public"
|
160
|
+
|
161
|
+
The Connect Gem will create/use schemas tied to the TaskIds coming out of Connect. In Development mode this TaskId will default to 1. To query data out in development mode you would open up rails console and execute `ActiveRecord::Base.connection.schema_search_path = 1` before proceeding to subsequent queries
|
162
|
+
|
163
|
+
## Delayed Job
|
164
|
+
|
165
|
+
In order to use delayed job the configuration option “delayed_job” must be set to true for jobs to be picked up by your workers
|
166
|
+
|
167
|
+
### Installation
|
168
|
+
1. Set `config.delayed_job = true` in `config/initializers/connect.rb`
|
169
|
+
2. Add the following line to the connect.rb init file `Dir["#{Rails.root}/lib/workers/*.rb"].each {|file| require file }`
|
170
|
+
3. Add the following gems to your gem file
|
171
|
+
```ruby
|
172
|
+
gem "delayed_job"
|
173
|
+
gem "delayed_job_active_record"
|
174
|
+
gem "daemons"
|
175
|
+
gem "delayed_job_web" #Optional if a web interface is needed for job management
|
176
|
+
```
|
177
|
+
4. Run `rails generate delayed_job:active_record` in the terminal
|
178
|
+
5. Add `config.active_job.queue_adapter = :delayed_job` to `config/application.rb`
|
179
|
+
|
180
|
+
### Usage
|
181
|
+
|
182
|
+
#### Creating a Worker Class
|
183
|
+
|
184
|
+
Add a worker file based on the following template to lib/workers/worker.rb
|
185
|
+
```ruby
|
186
|
+
class Worker
|
187
|
+
attr_accessor :schema
|
188
|
+
def initialize(instance_id,var2)
|
189
|
+
@instance_id = instance_id
|
190
|
+
@var2 = var2
|
191
|
+
@schema = ActiveRecord::Base.connection.schema_search_path
|
192
|
+
end
|
193
|
+
|
194
|
+
def perform()
|
195
|
+
@appinstance = ZuoraConnect::AppInstance.find(@instance_id)
|
196
|
+
@appinstance.new_session()
|
197
|
+
end
|
198
|
+
end
|
199
|
+
```
|
200
|
+
|
201
|
+
#### Queueing Jobs
|
202
|
+
|
203
|
+
Jobs can be queued anywhere in the code base by using the following code `Delayed::Job.enqueue(Worker.new(@appinstance.id, var2))`. Note that instead of passing in the @appinstance object we always pass in the id. This must happen for schema segmentation to work correctly. This can be disregarded if your worker is not processing data specific to a users app instance.
|
204
|
+
|
205
|
+
Reference [here](https://github.com/collectiveidea/delayed_job) for more information on Running Jobs and creating workers
|
206
|
+
|
207
|
+
#### Starting the delayed job daemon
|
208
|
+
|
209
|
+
Run `bin/delayed_job -n 2 restart` in your terminal to start 2 processes that will pick up all queued jobs
|
210
|
+
|
211
|
+
### License Information
|
212
|
+
IN THE EVENT YOU ARE AN EXISTING ZUORA CUSTOMER, USE OF THIS SOFTWARE IS GOVERNED BY THE MIT LICENSE SET FORTH BELOW AND NOT THE MASTER SUBSCRIPTION AGREEMENT OR OTHER COMMERCIAL AGREEMENT ENTERED INTO BETWEEN YOU AND ZUORA (“AGREEMENT”). FOR THE AVOIDANCE OF DOUBT, ZUORA’S OBLIGATIONS WITH RESPECT TO TECHNICAL SUPPORT, UPTIME, INDEMNIFICATION, AND SECURITY SET FORTH IN THE AGREEMENT DO NOT APPLY TO THE USE OF THIS SOFTWARE.
|
213
|
+
|
214
|
+
Copyright 2021 Zuora, Inc.
|
215
|
+
|
216
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
217
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
218
|
+
|
219
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
@@ -12,6 +12,7 @@ module ZuoraConnect
|
|
12
12
|
|
13
13
|
self.table_name = "zuora_connect_app_instances"
|
14
14
|
attr_accessor :options, :mode, :logins, :task_data, :last_refresh, :username, :password, :s3_client, :api_version, :drop_message, :new_session_message, :connect_user, :logitems, :user_timezone
|
15
|
+
@@telegraf_host = nil
|
15
16
|
REFRESH_TIMEOUT = 2.minute #Used to determine how long to wait on current refresh call before executing another
|
16
17
|
INSTANCE_REFRESH_WINDOW = 1.hours #Used to set how how long till app starts attempting to refresh cached task connect data
|
17
18
|
INSTANCE_REDIS_CACHE_PERIOD = 24.hours #Used to determine how long to cached task data will live for
|
@@ -348,7 +349,7 @@ module ZuoraConnect
|
|
348
349
|
|
349
350
|
def refresh(session: {})
|
350
351
|
refresh_count ||= 0
|
351
|
-
skip_connect ||=
|
352
|
+
skip_connect ||= ZuoraConnect.configuration.skip_connect
|
352
353
|
begin
|
353
354
|
#Check how app was deployed
|
354
355
|
if !self.auto_deployed? && !skip_connect
|
@@ -362,9 +363,9 @@ module ZuoraConnect
|
|
362
363
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("JSON parse error", response.body, response.code)
|
363
364
|
end
|
364
365
|
|
365
|
-
self.build_task(task_data: parsed_json, session: session)
|
366
|
+
self.build_task(task_data: parsed_json, session: session)
|
366
367
|
self.set_backup_creds
|
367
|
-
self.save(validate: false) if self.changed?
|
368
|
+
self.save(validate: false) if self.changed?
|
368
369
|
else
|
369
370
|
raise ZuoraConnect::Exceptions::ConnectCommunicationError.new("Error Communicating with Connect", response.body, response.code)
|
370
371
|
end
|
@@ -412,8 +413,8 @@ module ZuoraConnect
|
|
412
413
|
def set_backup_creds
|
413
414
|
if self.kms_key.present? && self.kms_key.match(/^arn:aws:.*/) && self.task_data.present?
|
414
415
|
self.zuora_logins = self.strip_cache_data(object: self.task_data.dup, keys: ['applications', 'tokens', 'user_settings'])
|
415
|
-
end
|
416
|
-
end
|
416
|
+
end
|
417
|
+
end
|
417
418
|
|
418
419
|
def zuora_logins=(val)
|
419
420
|
write_attribute(:zuora_logins, kms_encrypt(val.to_json))
|
@@ -478,6 +479,15 @@ module ZuoraConnect
|
|
478
479
|
end
|
479
480
|
Thread.current[:appinstance] = self
|
480
481
|
end
|
482
|
+
|
483
|
+
def self.write_to_telegraf(*args)
|
484
|
+
if ZuoraConnect.configuration.enable_metrics && !defined?(Prometheus)
|
485
|
+
@@telegraf_host = ZuoraConnect::Telegraf.new() if @@telegraf_host == nil
|
486
|
+
unicorn_stats = ZuoraObservability::Metrics.unicorn_listener if defined?(Unicorn) && Unicorn.respond_to?(:listener_names)
|
487
|
+
@@telegraf_host.write(direction: 'Raindrops', tags: {}, values: unicorn_stats) unless unicorn_stats.blank?
|
488
|
+
return @@telegraf_host.write(*args)
|
489
|
+
end
|
490
|
+
end
|
481
491
|
#### END Task Methods ####
|
482
492
|
|
483
493
|
#### START Task Methods ####
|
@@ -600,7 +610,10 @@ module ZuoraConnect
|
|
600
610
|
self.provisioned_app = nil
|
601
611
|
end
|
602
612
|
end
|
603
|
-
self.
|
613
|
+
if self.changed?
|
614
|
+
self.save(:validate => false)
|
615
|
+
self.refresh
|
616
|
+
end
|
604
617
|
|
605
618
|
return parsed_json
|
606
619
|
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
module ZuoraConnect
|
2
|
+
class Telegraf
|
3
|
+
attr_accessor :host
|
4
|
+
|
5
|
+
OUTBOUND_METRICS = true
|
6
|
+
OUTBOUND_METRICS_NAME = "request-outbound"
|
7
|
+
INBOUND_METRICS = true
|
8
|
+
INBOUND_METRICS_NAME = "request-inbound"
|
9
|
+
|
10
|
+
def initialize
|
11
|
+
self.connect
|
12
|
+
end
|
13
|
+
|
14
|
+
def connect
|
15
|
+
ZuoraConnect.logger.debug(self.format_metric_log('Telegraf','Need new connection')) if ZuoraConnect.configuration.telegraf_debug
|
16
|
+
uri = URI.parse(ZuoraConnect.configuration.telegraf_endpoint)
|
17
|
+
self.host = UDPSocket.new.tap do |socket|
|
18
|
+
socket.connect uri.host, uri.port
|
19
|
+
end
|
20
|
+
rescue => ex
|
21
|
+
self.host = nil
|
22
|
+
ZuoraConnect.logger.warn(self.format_metric_log('Telegraf', "Failed to connect: #{ex.class}")) if Rails.env.to_s != 'production'
|
23
|
+
end
|
24
|
+
|
25
|
+
def write(direction: 'Unknown', tags: {}, values: {})
|
26
|
+
time = Benchmark.measure do |bench|
|
27
|
+
# To avoid writing metrics from rspec tests
|
28
|
+
if Rails.env.to_sym != :test
|
29
|
+
app_instance = Thread.current[:appinstance].present? ? Thread.current[:appinstance].id : 0
|
30
|
+
tags = { app_name: ZuoraObservability::Env.app_name, process_type: ZuoraObservability::Env.process_type, app_instance: app_instance, pod_name: ZuoraObservability::Env.pod_name}.merge(tags)
|
31
|
+
|
32
|
+
if direction == :inbound
|
33
|
+
if INBOUND_METRICS && !Thread.current[:inbound_metric].to_bool
|
34
|
+
self.write_udp(series: INBOUND_METRICS_NAME, tags: tags, values: values)
|
35
|
+
Thread.current[:inbound_metric] = true
|
36
|
+
else
|
37
|
+
return
|
38
|
+
end
|
39
|
+
elsif direction == :outbound
|
40
|
+
self.write_udp(series: OUTBOUND_METRICS_NAME, tags: tags, values: values) if OUTBOUND_METRICS
|
41
|
+
else
|
42
|
+
self.write_udp(series: direction, tags: tags, values: values)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
if ZuoraConnect.configuration.telegraf_debug
|
47
|
+
ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', tags.to_s))
|
48
|
+
ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', values.to_s))
|
49
|
+
ZuoraConnect.logger.debug(self.format_metric_log('Telegraf', "Writing '#{direction.capitalize}': #{time.real.round(5)} ms"))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def write_udp(series: '', tags: {}, values: {})
|
55
|
+
return if !values.present?
|
56
|
+
self.host.write InfluxDB::PointValue.new({series: series, tags: tags, values: values}).dump
|
57
|
+
rescue => ex
|
58
|
+
self.connect
|
59
|
+
ZuoraConnect.logger.warn(self.format_metric_log('Telegraf',"Failed to write udp: #{ex.class}")) if Rails.env.to_s != 'production'
|
60
|
+
end
|
61
|
+
|
62
|
+
def format_metric_log(message, dump = nil)
|
63
|
+
message_color, dump_color = "1;91", "0;1"
|
64
|
+
log_entry = " \e[#{message_color}m#{message}\e[0m "
|
65
|
+
log_entry << "\e[#{dump_color}m%#{String === dump ? 's' : 'p'}\e[0m" % dump if dump
|
66
|
+
if Rails.env == :development
|
67
|
+
log_entry
|
68
|
+
else
|
69
|
+
[message, dump].compact.join(' - ')
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -2,6 +2,37 @@ module ZuoraConnect
|
|
2
2
|
class ZuoraUser < ActiveRecord::Base
|
3
3
|
self.table_name = "zuora_users"
|
4
4
|
attr_accessor :session
|
5
|
+
|
5
6
|
cattr_accessor :current_user_id
|
7
|
+
|
8
|
+
# zuora_user_id/zuora_entity_id both come from cookie or headers
|
9
|
+
# zuora_current_identity comes from session
|
10
|
+
# app_instance is only needed to try to migrate :/
|
11
|
+
def self.update_id_response(zuora_user_id, zuora_entity_id, zuora_current_identity, app_instance)
|
12
|
+
zuora_user = find_or_create_by!(zuora_user_id: zuora_user_id) do |user|
|
13
|
+
user.zuora_identity_response = { zuora_entity_id => zuora_current_identity }
|
14
|
+
end
|
15
|
+
|
16
|
+
if zuora_user.stale_identity?
|
17
|
+
zuora_user.zuora_identity_response[zuora_entity_id] = zuora_current_identity
|
18
|
+
zuora_user.save!
|
19
|
+
end
|
20
|
+
|
21
|
+
zuora_user
|
22
|
+
# NOTE(hartley): this rescue is deprecated. We should not be migrating in production
|
23
|
+
rescue ActiveRecord::StatementInvalid => e
|
24
|
+
raise unless e.message.include?('PG::UndefinedTable') && e.message.include?('zuora_users')
|
25
|
+
|
26
|
+
ZuoraConnect.logger.fatal('Error querying zuora_users table: attempting migration to recover')
|
27
|
+
|
28
|
+
app_instance.apartment_switch(nil, true)
|
29
|
+
retry
|
30
|
+
end
|
31
|
+
|
32
|
+
# NOTE(hartley): this value was extracted from original usage in helper,
|
33
|
+
# need to investigate when exactly the identity_response should be updated
|
34
|
+
def stale_identity?
|
35
|
+
updated_at < Time.now - 1.day
|
36
|
+
end
|
6
37
|
end
|
7
|
-
end
|
38
|
+
end
|
@@ -6,7 +6,7 @@ if defined?(Unicorn::WorkerKiller)
|
|
6
6
|
if defined?(Prometheus)
|
7
7
|
Prometheus::UNICORN_KILLS.set(1)
|
8
8
|
else
|
9
|
-
|
9
|
+
ZuoraConnect::AppInstance.write_to_telegraf(direction: 'Unicorn-Killer', tags: {app_instance: 0}, values: {kill: 1})
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
ZuoraObservability.configure do |config|
|
2
|
+
config.zecs_service_hook = lambda do |controller|
|
3
|
+
custom_payload = {}
|
4
|
+
if controller.instance_variable_defined?(:@appinstance)
|
5
|
+
appinstance = controller.instance_variable_get(:@appinstance)
|
6
|
+
if appinstance.logitems.present? && appinstance.logitems.class == Hash
|
7
|
+
ActiveSupport::Deprecation.warn("logitems is deprecated, please use zecs_service_hook. See 'https://gitlab.zeta.tools/extension-products/incubating-projects/zuora_observability/-/blob/master/doc/logging.md' for more details.")
|
8
|
+
custom_payload.merge!(appinstance.logitems)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
custom_payload
|
12
|
+
end
|
13
|
+
config.add_custom_payload_hook do |controller|
|
14
|
+
custom_payload = {}
|
15
|
+
if controller.instance_variable_defined?(:@appinstance)
|
16
|
+
appinstance = controller.instance_variable_get(:@appinstance)
|
17
|
+
custom_payload.merge!({ email: appinstance.connect_user })
|
18
|
+
end
|
19
|
+
custom_payload
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
module InfluxDB
|
2
|
+
# Convert data point to string using Line protocol
|
3
|
+
class PointValue
|
4
|
+
attr_reader :series, :values, :tags, :timestamp
|
5
|
+
|
6
|
+
def initialize(data)
|
7
|
+
@series = escape data[:series], :measurement
|
8
|
+
@values = escape_values data[:values]
|
9
|
+
@tags = escape_tags data[:tags]
|
10
|
+
@timestamp = data[:timestamp]
|
11
|
+
end
|
12
|
+
|
13
|
+
def dump
|
14
|
+
dump = @series.dup
|
15
|
+
dump << ",#{@tags}" if @tags
|
16
|
+
dump << " #{@values}"
|
17
|
+
dump << " #{@timestamp}" if @timestamp
|
18
|
+
dump
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
ESCAPES = {
|
24
|
+
measurement: [' '.freeze, ','.freeze],
|
25
|
+
tag_key: ['='.freeze, ' '.freeze, ','.freeze],
|
26
|
+
tag_value: ['='.freeze, ' '.freeze, ','.freeze],
|
27
|
+
field_key: ['='.freeze, ' '.freeze, ','.freeze, '"'.freeze],
|
28
|
+
field_value: ["\\".freeze, '"'.freeze],
|
29
|
+
}.freeze
|
30
|
+
|
31
|
+
private_constant :ESCAPES
|
32
|
+
|
33
|
+
def escape(str, type)
|
34
|
+
# rubocop:disable Layout/AlignParameters
|
35
|
+
str = str.encode "UTF-8".freeze, "UTF-8".freeze,
|
36
|
+
invalid: :replace,
|
37
|
+
undef: :replace,
|
38
|
+
replace: "".freeze
|
39
|
+
# rubocop:enable Layout/AlignParameters
|
40
|
+
|
41
|
+
ESCAPES[type].each do |ch|
|
42
|
+
str = str.gsub(ch) { "\\#{ch}" }
|
43
|
+
end
|
44
|
+
str
|
45
|
+
end
|
46
|
+
|
47
|
+
def escape_values(values)
|
48
|
+
return if values.nil?
|
49
|
+
values.map do |k, v|
|
50
|
+
key = escape(k.to_s, :field_key)
|
51
|
+
val = escape_value(v)
|
52
|
+
"#{key}=#{val}"
|
53
|
+
end.join(",".freeze)
|
54
|
+
end
|
55
|
+
|
56
|
+
def escape_value(value)
|
57
|
+
if value.is_a?(String)
|
58
|
+
'"'.freeze + escape(value, :field_value) + '"'.freeze
|
59
|
+
elsif value.is_a?(Integer)
|
60
|
+
"#{value}i"
|
61
|
+
else
|
62
|
+
value.to_s
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def escape_tags(tags)
|
67
|
+
return if tags.nil?
|
68
|
+
|
69
|
+
tags = tags.map do |k, v|
|
70
|
+
key = escape(k.to_s, :tag_key)
|
71
|
+
val = escape(v.to_s, :tag_value)
|
72
|
+
|
73
|
+
"#{key}=#{val}" unless key == "".freeze || val == "".freeze
|
74
|
+
end.compact
|
75
|
+
|
76
|
+
tags.join(",") unless tags.empty?
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
data/lib/metrics/net.rb
CHANGED
@@ -68,12 +68,12 @@ class HttpLogger
|
|
68
68
|
log_request_body(request)
|
69
69
|
log_request_headers(request)
|
70
70
|
if defined?(response) && response
|
71
|
-
tags = tags.merge({status: response.code.to_i})
|
71
|
+
tags = tags.merge({status: response.code.to_i})
|
72
72
|
log_response_code(response)
|
73
73
|
log_response_headers(response)
|
74
74
|
log_response_body(response.body)
|
75
75
|
end
|
76
|
-
|
76
|
+
ZuoraConnect::AppInstance.write_to_telegraf(direction: :outbound, tags: tags, values: values)
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
@@ -95,7 +95,7 @@ class HttpLogger
|
|
95
95
|
end
|
96
96
|
|
97
97
|
HTTP_METHODS_WITH_BODY = Set.new(%w(POST PUT GET PATCH))
|
98
|
-
|
98
|
+
|
99
99
|
def log_request_body(request)
|
100
100
|
if self.class.log_request_body
|
101
101
|
if HTTP_METHODS_WITH_BODY.include?(request.method)
|
@@ -149,8 +149,8 @@ class HttpLogger
|
|
149
149
|
def truncate_body(body)
|
150
150
|
if collapse_body_limit && collapse_body_limit > 0 && body && body.size >= collapse_body_limit
|
151
151
|
body_piece_size = collapse_body_limit / 2
|
152
|
-
body[0..body_piece_size] +
|
153
|
-
"\n\n<some data truncated>\n\n" +
|
152
|
+
body[0..body_piece_size] +
|
153
|
+
"\n\n<some data truncated>\n\n" +
|
154
154
|
body[(body.size - body_piece_size)..body.size]
|
155
155
|
else
|
156
156
|
body
|
@@ -203,7 +203,7 @@ class Net::HTTP
|
|
203
203
|
|
204
204
|
def request(request, body = nil, &block)
|
205
205
|
HttpLogger.perform(self, request, body) do
|
206
|
-
request_without_logging(request, body, &block)
|
206
|
+
request_without_logging(request, body, &block)
|
207
207
|
end
|
208
208
|
end
|
209
209
|
end
|
@@ -215,4 +215,4 @@ if defined?(Rails)
|
|
215
215
|
HttpLogger.logger = ZuoraConnect.logger unless HttpLogger.logger
|
216
216
|
end
|
217
217
|
end
|
218
|
-
end
|
218
|
+
end
|
@@ -1,6 +1,37 @@
|
|
1
1
|
module ZuoraConnect
|
2
2
|
require 'uri'
|
3
3
|
|
4
|
+
# Object of this class is passed to the ActiveSupport::Notification hook
|
5
|
+
class PageRequest
|
6
|
+
|
7
|
+
# This method is triggered when a non error page is loaded (not 404)
|
8
|
+
def call(name, started, finished, unique_id, payload)
|
9
|
+
# If the url contains any css or JavaScript files then do not collect metrics for them
|
10
|
+
return nil if ["css", "assets", "jpg", "png", "jpeg", "ico"].any? { |word| payload[:path].include?(word) }
|
11
|
+
|
12
|
+
# Getting the endpoint and the content_type
|
13
|
+
content_hash = {:html => "text/html", :js => "application/javascript", :json => "application/json", :csv => "text/csv"}
|
14
|
+
content_type = content_hash.key?(payload[:format]) ? content_hash[payload[:format]] : payload[:format]
|
15
|
+
content_type = content_type.to_s.gsub('text/javascript', 'application/javascript')
|
16
|
+
|
17
|
+
# payloads with 500 requests do not have status as it is not set by the controller
|
18
|
+
# https://github.com/rails/rails/issues/33335
|
19
|
+
#status_code = payload[:status] ? payload[:status] : payload[:exception_object].present? ? 500 : ""
|
20
|
+
if payload[:exception].present?
|
21
|
+
status_code, exception = [500, payload[:exception].first]
|
22
|
+
else
|
23
|
+
status_code, exception = [payload[:status], nil]
|
24
|
+
end
|
25
|
+
|
26
|
+
tags = {method: payload[:method], status: status_code, error_type: exception, content_type: content_type, controller: payload[:controller], action: payload[:action]}.compact
|
27
|
+
|
28
|
+
values = {view_time: payload[:view_runtime], db_time: payload[:db_runtime], response_time: ((finished-started)*1000)}.compact
|
29
|
+
values = values.map{ |k,v| [k,v.round(2)]}.to_h
|
30
|
+
|
31
|
+
ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
4
35
|
class MetricsMiddleware
|
5
36
|
|
6
37
|
require "zuora_connect/version"
|
@@ -36,9 +67,9 @@ module ZuoraConnect
|
|
36
67
|
if defined?(Prometheus) && env['PATH_INFO'] == '/connect/internal/metrics'
|
37
68
|
|
38
69
|
# Prometheus Stuff
|
39
|
-
metrics = ZuoraObservability::Metrics.resque
|
70
|
+
metrics = ZuoraObservability::Metrics.resque
|
40
71
|
metrics = defined?(ZuoraConnect::AppInstance.get_metrics) ? ZuoraConnect::AppInstance.get_metrics(metrics) : metrics
|
41
|
-
|
72
|
+
|
42
73
|
redis_up = metrics.present? && metrics.dig(:Resque, :Workers_Total).present? ? 1 : 0
|
43
74
|
Prometheus::REDIS_CONNECTION.set(redis_up)
|
44
75
|
|
@@ -77,7 +108,7 @@ module ZuoraConnect
|
|
77
108
|
|
78
109
|
values = {response_time: ((Time.now - start_time)*1000).round(2) }
|
79
110
|
|
80
|
-
|
111
|
+
ZuoraConnect::AppInstanceBase.write_to_telegraf(direction: :inbound, tags: tags, values: values)
|
81
112
|
end
|
82
113
|
end
|
83
114
|
Thread.current[:inbound_metric] = nil
|
data/lib/zuora_connect.rb
CHANGED
@@ -9,8 +9,8 @@ require 'resque/silence_done'
|
|
9
9
|
require 'resque/self_lookup'
|
10
10
|
require 'resque/plugins/custom_logger'
|
11
11
|
require 'resque/plugins/app_instance_job'
|
12
|
+
require 'metrics/influx/point_value'
|
12
13
|
require 'metrics/net'
|
13
|
-
require 'mono_logger'
|
14
14
|
require 'zuora_connect/zuora_audit'
|
15
15
|
require 'active_record'
|
16
16
|
require 'zuora_observability'
|
@@ -87,7 +87,7 @@ module ZuoraConnect
|
|
87
87
|
verify_server_cert: false,
|
88
88
|
log_level: Logger::INFO,
|
89
89
|
service_name: ENV['DEIS_APP'].present? ? ENV['DEIS_APP'] : Rails.application.class.parent_name,
|
90
|
-
logger: ZuoraObservability::Logger.custom_logger(name: "ElasticAPM", level:
|
90
|
+
logger: ZuoraObservability::Logger.custom_logger(name: "ElasticAPM", level: Logger::WARN)
|
91
91
|
})
|
92
92
|
defaults.merge!({disable_send: true}) if defined?(Rails::Console)
|
93
93
|
|
@@ -7,7 +7,7 @@ module ZuoraConnect
|
|
7
7
|
|
8
8
|
attr_accessor :oauth_client_id, :oauth_client_secret, :oauth_client_redirect_uri
|
9
9
|
|
10
|
-
attr_accessor :dev_mode_logins, :dev_mode_options, :dev_mode_mode, :dev_mode_appinstance, :dev_mode_user, :dev_mode_pass, :dev_mode_admin, :dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :
|
10
|
+
attr_accessor :dev_mode_logins, :dev_mode_options, :dev_mode_mode, :dev_mode_appinstance, :dev_mode_user, :dev_mode_pass, :dev_mode_admin, :dev_mode_secret_access_key,:dev_mode_access_key_id,:aws_region, :s3_bucket_name, :s3_folder_name, :insert_migrations, :skip_connect
|
11
11
|
|
12
12
|
def initialize
|
13
13
|
@default_locale = :en
|
@@ -20,6 +20,7 @@ module ZuoraConnect
|
|
20
20
|
@silencer_resque_finish = true
|
21
21
|
@blpop_queue = false
|
22
22
|
@insert_migrations = true
|
23
|
+
@skip_connect = false
|
23
24
|
|
24
25
|
# Setting the app name for telegraf write
|
25
26
|
@enable_metrics = false
|
@@ -43,7 +44,6 @@ module ZuoraConnect
|
|
43
44
|
@aws_region = "us-west-2"
|
44
45
|
@s3_bucket_name = "rbm-apps"
|
45
46
|
@s3_folder_name = Rails.application.class.parent_name
|
46
|
-
@json_logging = Rails.env.development? || Rails.env.test? ? false : true
|
47
47
|
end
|
48
48
|
|
49
49
|
def private_key
|
@@ -125,7 +125,7 @@ module ZuoraConnect
|
|
125
125
|
PaperTrail.whodunnit = session["#{@appinstance.id}::user::email"] if defined?(PaperTrail)
|
126
126
|
end
|
127
127
|
|
128
|
-
locale = (session["#{@appinstance.id}::user::locale"] || "").gsub("_", "-")
|
128
|
+
locale = (session["#{@appinstance.id}::user::locale"] || "").gsub("_", "-")
|
129
129
|
begin
|
130
130
|
I18n.locale = locale.present? ? locale : @appinstance.locale
|
131
131
|
rescue I18n::InvalidLocale => ex
|
@@ -303,8 +303,8 @@ module ZuoraConnect
|
|
303
303
|
private
|
304
304
|
def setup_instance_via_prod_mode
|
305
305
|
zuora_entity_id = request.headers['ZuoraCurrentEntity'] || cookies['ZuoraCurrentEntity']
|
306
|
-
ZuoraConnect::ZuoraUser.current_user_id = nil
|
307
|
-
|
306
|
+
ZuoraConnect::ZuoraUser.current_user_id = nil
|
307
|
+
|
308
308
|
if zuora_entity_id.present?
|
309
309
|
zuora_tenant_id = cookies['Zuora-Tenant-Id']
|
310
310
|
zuora_user_id = cookies['Zuora-User-Id']
|
@@ -417,28 +417,10 @@ module ZuoraConnect
|
|
417
417
|
|
418
418
|
# One deployed instance with credentials
|
419
419
|
if defined?(@appinstance) && !@appinstance['zuora_logins'].nil?
|
420
|
-
|
421
|
-
|
422
|
-
|
423
|
-
|
424
|
-
rescue ActiveRecord::StatementInvalid => ex
|
425
|
-
if ex.message.include?("PG::UndefinedTable") && ex.message.include?("zuora_users")
|
426
|
-
@appinstance.apartment_switch(nil,true)
|
427
|
-
retry
|
428
|
-
else
|
429
|
-
raise
|
430
|
-
end
|
431
|
-
end
|
432
|
-
if @zuora_user.present?
|
433
|
-
ZuoraConnect.logger.debug("Current zuora user #{zuora_user_id}")
|
434
|
-
if @zuora_user.updated_at < Time.now - 1.day
|
435
|
-
@zuora_user.zuora_identity_response[zuora_entity_id] = session["ZuoraCurrentIdentity"]
|
436
|
-
@zuora_user.save!
|
437
|
-
end
|
438
|
-
else
|
439
|
-
ZuoraConnect.logger.debug("New zuora user object for #{zuora_user_id}")
|
440
|
-
@zuora_user = ZuoraConnect::ZuoraUser.create!(:zuora_user_id => zuora_user_id, :zuora_identity_response => {zuora_entity_id => session["ZuoraCurrentIdentity"]})
|
441
|
-
end
|
420
|
+
@zuora_user = ZuoraConnect::ZuoraUser.update_id_response(
|
421
|
+
zuora_user_id, zuora_entity_id, session["ZuoraCurrentIdentity"],
|
422
|
+
@appinstance
|
423
|
+
)
|
442
424
|
@zuora_user.session = session
|
443
425
|
ZuoraConnect::ZuoraUser.current_user_id = zuora_user_id
|
444
426
|
session["#{@appinstance.id}::user::localUserId"] = @zuora_user.id
|
@@ -682,15 +664,15 @@ module ZuoraConnect
|
|
682
664
|
def setup_instance_via_dev_mode
|
683
665
|
session["appInstance"] = ZuoraConnect.configuration.dev_mode_appinstance
|
684
666
|
session["#{ZuoraConnect.configuration.dev_mode_appinstance}::admin"] = ZuoraConnect.configuration.dev_mode_admin
|
685
|
-
|
667
|
+
|
686
668
|
values = {
|
687
669
|
id: ZuoraConnect.configuration.dev_mode_appinstance,
|
688
|
-
access_token: ZuoraConnect.configuration.dev_mode_user,
|
689
|
-
refresh_token: ZuoraConnect.configuration.dev_mode_pass,
|
690
|
-
token: ZuoraConnect.configuration.dev_mode_pass+ZuoraConnect.configuration.dev_mode_pass,
|
670
|
+
access_token: ZuoraConnect.configuration.dev_mode_user,
|
671
|
+
refresh_token: ZuoraConnect.configuration.dev_mode_pass,
|
672
|
+
token: ZuoraConnect.configuration.dev_mode_pass+ZuoraConnect.configuration.dev_mode_pass,
|
691
673
|
api_token: ZuoraConnect.configuration.dev_mode_pass+ZuoraConnect.configuration.dev_mode_pass
|
692
674
|
}
|
693
|
-
|
675
|
+
|
694
676
|
@appinstance = ZuoraConnect::AppInstance.find_by(:id => ZuoraConnect.configuration.dev_mode_appinstance.to_i)
|
695
677
|
ZuoraConnect::ZuoraUser.current_user_id = 0
|
696
678
|
if @appinstance.blank?
|
@@ -708,4 +690,4 @@ module ZuoraConnect
|
|
708
690
|
end
|
709
691
|
end
|
710
692
|
end
|
711
|
-
end
|
693
|
+
end
|
@@ -32,5 +32,8 @@ module ZuoraConnect
|
|
32
32
|
app.config.middleware.use Rack::Deflater, if: ->(env, *) { env['PATH_INFO'] == '/connect/internal/metrics' }
|
33
33
|
end
|
34
34
|
end
|
35
|
+
|
36
|
+
# hook to process_action
|
37
|
+
ActiveSupport::Notifications.subscribe('process_action.action_controller', ZuoraConnect::PageRequest.new)
|
35
38
|
end
|
36
39
|
end
|
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: 3.0.0.pre.
|
4
|
+
version: 3.0.0.pre.r
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Connect Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: apartment
|
@@ -38,40 +38,20 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: ougai-formatters-customizable
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - '='
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: 1.0.0
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - '='
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 1.0.0
|
55
41
|
- !ruby/object:Gem::Dependency
|
56
42
|
name: zuora_api
|
57
43
|
requirement: !ruby/object:Gem::Requirement
|
58
44
|
requirements:
|
59
45
|
- - "~>"
|
60
46
|
- !ruby/object:Gem::Version
|
61
|
-
version: 1.7
|
62
|
-
- - ">="
|
63
|
-
- !ruby/object:Gem::Version
|
64
|
-
version: 1.7.00
|
47
|
+
version: '1.7'
|
65
48
|
type: :runtime
|
66
49
|
prerelease: false
|
67
50
|
version_requirements: !ruby/object:Gem::Requirement
|
68
51
|
requirements:
|
69
52
|
- - "~>"
|
70
53
|
- !ruby/object:Gem::Version
|
71
|
-
version: 1.7
|
72
|
-
- - ">="
|
73
|
-
- !ruby/object:Gem::Version
|
74
|
-
version: 1.7.00
|
54
|
+
version: '1.7'
|
75
55
|
- !ruby/object:Gem::Dependency
|
76
56
|
name: httparty
|
77
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,20 +72,6 @@ dependencies:
|
|
92
72
|
- - ">="
|
93
73
|
- !ruby/object:Gem::Version
|
94
74
|
version: 0.16.4
|
95
|
-
- !ruby/object:Gem::Dependency
|
96
|
-
name: lograge
|
97
|
-
requirement: !ruby/object:Gem::Requirement
|
98
|
-
requirements:
|
99
|
-
- - ">="
|
100
|
-
- !ruby/object:Gem::Version
|
101
|
-
version: '0'
|
102
|
-
type: :runtime
|
103
|
-
prerelease: false
|
104
|
-
version_requirements: !ruby/object:Gem::Requirement
|
105
|
-
requirements:
|
106
|
-
- - ">="
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
version: '0'
|
109
75
|
- !ruby/object:Gem::Dependency
|
110
76
|
name: aws-sdk-s3
|
111
77
|
requirement: !ruby/object:Gem::Requirement
|
@@ -134,20 +100,6 @@ dependencies:
|
|
134
100
|
- - ">="
|
135
101
|
- !ruby/object:Gem::Version
|
136
102
|
version: '0'
|
137
|
-
- !ruby/object:Gem::Dependency
|
138
|
-
name: mono_logger
|
139
|
-
requirement: !ruby/object:Gem::Requirement
|
140
|
-
requirements:
|
141
|
-
- - "~>"
|
142
|
-
- !ruby/object:Gem::Version
|
143
|
-
version: '1.0'
|
144
|
-
type: :runtime
|
145
|
-
prerelease: false
|
146
|
-
version_requirements: !ruby/object:Gem::Requirement
|
147
|
-
requirements:
|
148
|
-
- - "~>"
|
149
|
-
- !ruby/object:Gem::Version
|
150
|
-
version: '1.0'
|
151
103
|
- !ruby/object:Gem::Dependency
|
152
104
|
name: railties
|
153
105
|
requirement: !ruby/object:Gem::Requirement
|
@@ -186,16 +138,16 @@ dependencies:
|
|
186
138
|
name: zuora_observability
|
187
139
|
requirement: !ruby/object:Gem::Requirement
|
188
140
|
requirements:
|
189
|
-
- -
|
141
|
+
- - "~>"
|
190
142
|
- !ruby/object:Gem::Version
|
191
|
-
version: 0.1
|
143
|
+
version: '0.1'
|
192
144
|
type: :runtime
|
193
145
|
prerelease: false
|
194
146
|
version_requirements: !ruby/object:Gem::Requirement
|
195
147
|
requirements:
|
196
|
-
- -
|
148
|
+
- - "~>"
|
197
149
|
- !ruby/object:Gem::Version
|
198
|
-
version: 0.1
|
150
|
+
version: '0.1'
|
199
151
|
- !ruby/object:Gem::Dependency
|
200
152
|
name: rspec
|
201
153
|
requirement: !ruby/object:Gem::Requirement
|
@@ -281,7 +233,7 @@ dependencies:
|
|
281
233
|
- !ruby/object:Gem::Version
|
282
234
|
version: '0'
|
283
235
|
- !ruby/object:Gem::Dependency
|
284
|
-
name:
|
236
|
+
name: factory_bot_rails
|
285
237
|
requirement: !ruby/object:Gem::Requirement
|
286
238
|
requirements:
|
287
239
|
- - ">="
|
@@ -336,6 +288,48 @@ dependencies:
|
|
336
288
|
- - ">="
|
337
289
|
- !ruby/object:Gem::Version
|
338
290
|
version: '0'
|
291
|
+
- !ruby/object:Gem::Dependency
|
292
|
+
name: rubocop
|
293
|
+
requirement: !ruby/object:Gem::Requirement
|
294
|
+
requirements:
|
295
|
+
- - ">="
|
296
|
+
- !ruby/object:Gem::Version
|
297
|
+
version: '0'
|
298
|
+
type: :development
|
299
|
+
prerelease: false
|
300
|
+
version_requirements: !ruby/object:Gem::Requirement
|
301
|
+
requirements:
|
302
|
+
- - ">="
|
303
|
+
- !ruby/object:Gem::Version
|
304
|
+
version: '0'
|
305
|
+
- !ruby/object:Gem::Dependency
|
306
|
+
name: rubocop-rails
|
307
|
+
requirement: !ruby/object:Gem::Requirement
|
308
|
+
requirements:
|
309
|
+
- - ">="
|
310
|
+
- !ruby/object:Gem::Version
|
311
|
+
version: '0'
|
312
|
+
type: :development
|
313
|
+
prerelease: false
|
314
|
+
version_requirements: !ruby/object:Gem::Requirement
|
315
|
+
requirements:
|
316
|
+
- - ">="
|
317
|
+
- !ruby/object:Gem::Version
|
318
|
+
version: '0'
|
319
|
+
- !ruby/object:Gem::Dependency
|
320
|
+
name: rubocop-rspec
|
321
|
+
requirement: !ruby/object:Gem::Requirement
|
322
|
+
requirements:
|
323
|
+
- - ">="
|
324
|
+
- !ruby/object:Gem::Version
|
325
|
+
version: '0'
|
326
|
+
type: :development
|
327
|
+
prerelease: false
|
328
|
+
version_requirements: !ruby/object:Gem::Requirement
|
329
|
+
requirements:
|
330
|
+
- - ">="
|
331
|
+
- !ruby/object:Gem::Version
|
332
|
+
version: '0'
|
339
333
|
description: Description of Connect.
|
340
334
|
email:
|
341
335
|
- connect@zuora.com
|
@@ -344,6 +338,7 @@ extensions: []
|
|
344
338
|
extra_rdoc_files: []
|
345
339
|
files:
|
346
340
|
- MIT-LICENSE
|
341
|
+
- README.md
|
347
342
|
- Rakefile
|
348
343
|
- app/assets/javascripts/hallway_wrapper/after.js
|
349
344
|
- app/assets/javascripts/hallway_wrapper/before.js
|
@@ -360,6 +355,7 @@ files:
|
|
360
355
|
- app/models/zuora_connect/app_instance.rb
|
361
356
|
- app/models/zuora_connect/app_instance_base.rb
|
362
357
|
- app/models/zuora_connect/login.rb
|
358
|
+
- app/models/zuora_connect/telegraf.rb
|
363
359
|
- app/models/zuora_connect/zuora_user.rb
|
364
360
|
- app/views/layouts/zuora_connect/application.html.erb
|
365
361
|
- app/views/sql/refresh_aggregate_table.txt
|
@@ -378,6 +374,7 @@ files:
|
|
378
374
|
- config/initializers/resque.rb
|
379
375
|
- config/initializers/to_bool.rb
|
380
376
|
- config/initializers/unicorn.rb
|
377
|
+
- config/initializers/zuora_observability.rb
|
381
378
|
- config/routes.rb
|
382
379
|
- db/migrate/20100718151733_create_connect_app_instances.rb
|
383
380
|
- db/migrate/20101024162319_add_tokens_to_app_instance.rb
|
@@ -394,6 +391,7 @@ files:
|
|
394
391
|
- db/migrate/20190520232222_add_unique_index.rb
|
395
392
|
- db/migrate/20190520232223_add_provisioning_fields.rb
|
396
393
|
- db/migrate/20190520232224_add_environment_fields.rb
|
394
|
+
- lib/metrics/influx/point_value.rb
|
397
395
|
- lib/metrics/net.rb
|
398
396
|
- lib/middleware/bad_multipart_form_data_sanitizer.rb
|
399
397
|
- lib/middleware/json_parse_errors.rb
|
@@ -432,7 +430,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
432
430
|
- !ruby/object:Gem::Version
|
433
431
|
version: 1.3.1
|
434
432
|
requirements: []
|
435
|
-
rubygems_version: 3.
|
433
|
+
rubygems_version: 3.2.3
|
436
434
|
signing_key:
|
437
435
|
specification_version: 4
|
438
436
|
summary: Summary of Connect.
|