moesif_rack 1.3.5 → 1.3.10

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c829d3004e26c40536debc186d0c45a8a3cf08d854c75f0cf76dce20d142e951
4
- data.tar.gz: ac8c4d6c2c66dae5348b7421128fdd6b5ce0b2c9a48e1712aa632817f2ade291
3
+ metadata.gz: 5449e55b2da865cdc2bd4d52eef977b45db5a3e7648ee18f67f93795bf1fcd46
4
+ data.tar.gz: 930c9fb3a9181eec3b12d5aea8073c12646f94f77d16638dfa0422107b8000f3
5
5
  SHA512:
6
- metadata.gz: 7f10f8c2e8c4cb8af3d55a4d5aee69626ddb893405ba866578af506834516848b5367f5361a07ca5eb6acb3adccae2a8429432d8792cfb197391b42db310dab6
7
- data.tar.gz: 3ee6984671ab33f20dcf4b6b640935e315cc84c68e39bb9093b77a9e632aa3683e0e213d197140baa93f76f14809e0d19f701710900f0edc1e9575182121c27f
6
+ metadata.gz: 13012b377dac7ca5da3dcaf1d50ef97e71f6515df9e7f94e61b39746b4f29b134efcbc87eaafcb8dcd04dd67e0e052d8f0c5e9c77dd6ea20a7d997f50df3feb6
7
+ data.tar.gz: d7499b20fa602a2dd1bde29099b5b11755f36421f79c32f59fc1e1aa7f0e1dce7794b7ed1ca703c74ff07f040492b3ecc12f038eb3f52625348b13ae9becb2ec
data/README.md CHANGED
@@ -22,7 +22,7 @@ gem install moesif_rack
22
22
  and if you have a `Gemfile` in your project, please add this line to
23
23
 
24
24
  ```
25
- gem 'moesif_rack', '~> 1.3.4'
25
+ gem 'moesif_rack', '~> 1.3.9'
26
26
 
27
27
  ```
28
28
 
@@ -126,12 +126,10 @@ Optional.
126
126
  identify_user is a Proc that takes env, headers, and body as arguments and returns a user_id string. This helps us attribute requests to unique users. Even though Moesif can automatically retrieve the user_id without this, this is highly recommended to ensure accurate attribution.
127
127
 
128
128
  ```ruby
129
-
130
129
  moesif_options['identify_user'] = Proc.new { |env, headers, body|
131
130
 
132
- #snip
133
-
134
- 'my_user_id'
131
+ # Add your custom code that returns a string for user id
132
+ '12345'
135
133
  }
136
134
 
137
135
  ```
@@ -145,13 +143,24 @@ identify_company is a Proc that takes env, headers, and body as arguments and re
145
143
 
146
144
  moesif_options['identify_company'] = Proc.new { |env, headers, body|
147
145
 
148
- #snip
149
-
150
- 'my_company_id'
146
+ # Add your custom code that returns a string for company id
147
+ '67890'
151
148
  }
152
149
 
153
150
  ```
154
151
 
152
+ #### __`identify_session`__
153
+
154
+ Optional. A Proc that takes env, headers, body and returns a string.
155
+
156
+ ```ruby
157
+
158
+ moesif_options['identify_session'] = Proc.new { |env, headers, body|
159
+ # Add your custom code that returns a string for session/API token
160
+ 'XXXXXXXXX'
161
+ }
162
+ ```
163
+
155
164
  #### __`get_metadata`__
156
165
 
157
166
  Optional.
@@ -162,31 +171,15 @@ metadata to this event.
162
171
  ```ruby
163
172
 
164
173
  moesif_options['get_metadata'] = Proc.new { |env, headers, body|
165
-
166
- #snip
174
+ # Add your custom code that returns a dictionary
167
175
  value = {
168
- 'foo' => 'abc',
169
- 'bar' => '123'
176
+ 'datacenter' => 'westus',
177
+ 'deployment_version' => 'v1.2.3'
170
178
  }
171
-
172
179
  value
173
180
  }
174
181
  ```
175
182
 
176
- #### __`identify_session`__
177
-
178
- Optional. A Proc that takes env, headers, body and returns a string.
179
-
180
- ```ruby
181
-
182
- moesif_options['identify_session'] = Proc.new { |env, headers, body|
183
-
184
- #snip
185
-
186
- 'the_session_token'
187
- }
188
-
189
- ```
190
183
 
191
184
  #### __`mask_data`__
192
185
 
@@ -196,9 +189,8 @@ With mask_data, you can make modifications to headers or body of the event befor
196
189
  ```ruby
197
190
 
198
191
  moesif_options['mask_data'] = Proc.new { |event_model|
199
-
200
- #snip
201
-
192
+ # Add your custom code that returns a event_model after modifying any fields
193
+ event_model.response.body.password = nil
202
194
  event_model
203
195
  }
204
196
 
@@ -213,9 +205,7 @@ Optional. A Proc that takes env, headers, body and returns a boolean.
213
205
  ```ruby
214
206
 
215
207
  moesif_options['skip'] = Proc.new { |env, headers, body|
216
-
217
- #snip
218
-
208
+ # Add your custom code that returns true to skip logging the API call
219
209
  false
220
210
  }
221
211
 
@@ -232,7 +222,7 @@ Optional. Boolean. Default false. If true, it will print out debug messages. In
232
222
 
233
223
  Optional. Boolean. Default true. If false, will not log request and response body to Moesif.
234
224
 
235
- #### __`capture_outoing_requests`__
225
+ #### __`capture_outgoing_requests`__
236
226
  Optional. boolean, Default `false`. Set to `true` to capture all outgoing API calls from your app to third parties like Stripe, Github or to your own dependencies while using [Net::HTTP](https://ruby-doc.org/stdlib-2.6.3/libdoc/net/http/rdoc/Net/HTTP.html) package. The options below is applied to outgoing API calls. When the request is outgoing, for options functions that take request and response as input arguments, the request and response objects passed in are [Request](https://www.rubydoc.info/stdlib/net/Net/HTTPRequest) request and [Response](https://www.rubydoc.info/stdlib/net/Net/HTTPResponse) response objects.
237
227
 
238
228
 
@@ -245,9 +235,8 @@ identify_user_outgoing is a Proc that takes request and response as arguments an
245
235
 
246
236
  moesif_options['identify_user_outgoing'] = Proc.new { |request, response|
247
237
 
248
- #snip
249
-
250
- 'the_user_id'
238
+ # Add your custom code that returns a string for user id
239
+ '12345'
251
240
  }
252
241
 
253
242
  ```
@@ -261,9 +250,8 @@ identify_company_outgoing is a Proc that takes request and response as arguments
261
250
 
262
251
  moesif_options['identify_company_outgoing'] = Proc.new { |request, response|
263
252
 
264
- #snip
265
-
266
- 'the_company_id'
253
+ # Add your custom code that returns a string for company id
254
+ '67890'
267
255
  }
268
256
 
269
257
  ```
@@ -279,12 +267,11 @@ metadata to this event.
279
267
 
280
268
  moesif_options['get_metadata_outgoing'] = Proc.new { |request, response|
281
269
 
282
- #snip
270
+ # Add your custom code that returns a dictionary
283
271
  value = {
284
- 'foo' => 'abc',
285
- 'bar' => '123'
272
+ 'datacenter' => 'westus',
273
+ 'deployment_version' => 'v1.2.3'
286
274
  }
287
-
288
275
  value
289
276
  }
290
277
  ```
@@ -297,9 +284,8 @@ Optional. A Proc that takes request, response and returns a string.
297
284
 
298
285
  moesif_options['identify_session_outgoing'] = Proc.new { |request, response|
299
286
 
300
- #snip
301
-
302
- 'the_session_token'
287
+ # Add your custom code that returns a string for session/API token
288
+ 'XXXXXXXXX'
303
289
  }
304
290
 
305
291
  ```
@@ -312,8 +298,7 @@ Optional. A Proc that takes request, response and returns a boolean. If `true` w
312
298
 
313
299
  moesif_options['skip_outgoing'] = Proc.new{ |request, response|
314
300
 
315
- #snip
316
-
301
+ # Add your custom code that returns true to skip logging the API call
317
302
  false
318
303
  }
319
304
 
@@ -328,8 +313,8 @@ With mask_data_outgoing, you can make modifications to headers or body of the ev
328
313
 
329
314
  moesif_options['mask_data_outgoing'] = Proc.new { |event_model|
330
315
 
331
- #snip
332
-
316
+ # Add your custom code that returns a event_model after modifying any fields
317
+ event_model.response.body.password = nil
333
318
  event_model
334
319
  }
335
320
 
@@ -341,28 +326,51 @@ Optional. Boolean. Default true. If false, will not log request and response bod
341
326
 
342
327
  ## Update User
343
328
 
344
- ### update_user method
345
- A method is attached to the moesif middleware object to update the user profile or metadata.
346
- The metadata field can be any custom data you want to set on the user. The `user_id` field is required.
329
+ ### Update a Single User
330
+ Create or update a user profile in Moesif.
331
+ The metadata field can be any customer demographic or other info you want to store.
332
+ Only the `user_id` field is required.
333
+ This method is a convenient helper that calls the Moesif API lib.
334
+ For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-a-user).
347
335
 
348
336
  ```ruby
349
- metadata = JSON.parse('{'\
350
- '"email": "testrubyapi@user.com",'\
351
- '"name": "ruby api user",'\
352
- '"custom": "testdata"'\
353
- '}')
337
+ metadata => {
338
+ :email => 'john@acmeinc.com',
339
+ :first_name => 'John',
340
+ :last_name => 'Doe',
341
+ :title => 'Software Engineer',
342
+ :salesInfo => {
343
+ :stage => 'Customer',
344
+ :lifetime_value => 24000,
345
+ :accountOwner => 'mary@contoso.com',
346
+ }
347
+ }
354
348
 
355
- user_model = { "user_id" => "12345",
356
- "company_id" => "67890",
357
- "modified_time" => Time.now.utc.iso8601,
358
- "metadata" => metadata }
349
+ # Campaign object is optional, but useful if you want to track ROI of acquisition channels
350
+ # See https://www.moesif.com/docs/api#users for campaign schema
351
+ campaign = CampaignModel.new()
352
+ campaign.utm_source = "google"
353
+ campaign.utm_medium = "cpc"
354
+ campaign.utm_campaign = "adwords"
355
+ campaign.utm_term = "api+tooling"
356
+ campaign.utm_content = "landing"
357
+
358
+ # Only user_id is required.
359
+ # metadata can be any custom object
360
+ user = UserModel.new()
361
+ user.user_id = "12345"
362
+ user.company_id = "67890" # If set, associate user with a company object
363
+ user.campaign = campaign
364
+ user.metadata = metadata
359
365
 
360
366
  update_user = MoesifRack::MoesifMiddleware.new(@app, @options).update_user(user_model)
361
367
  ```
362
368
 
363
- ### update_users_batch method
364
- A method is attached to the moesif middleware object to update the users profile or metadata in batch.
365
- The metadata field can be any custom data you want to set on the user. The `user_id` field is required.
369
+ ### Update Users in Batch
370
+ Similar to update_user, but used to update a list of users in one batch.
371
+ Only the `user_id` field is required.
372
+ This method is a convenient helper that calls the Moesif API lib.
373
+ For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-users-in-batch).
366
374
 
367
375
  ```ruby
368
376
  metadata = JSON.parse('{'\
@@ -371,45 +379,88 @@ metadata = JSON.parse('{'\
371
379
  '"custom": "testdata"'\
372
380
  '}')
373
381
 
374
- user_models = []
375
-
376
- user_model_A = { "user_id" => "12345",
377
- "company_id" => "67890",
378
- "modified_time" => Time.now.utc.iso8601,
379
- "metadata" => metadata }
380
-
381
- user_model_B = { "user_id" => "1234",
382
- "company_id" => "6789",
383
- "modified_time" => Time.now.utc.iso8601,
384
- "metadata" => metadata }
382
+ users = []
383
+
384
+ metadata => {
385
+ :email => 'john@acmeinc.com',
386
+ :first_name => 'John',
387
+ :last_name => 'Doe',
388
+ :title => 'Software Engineer',
389
+ :salesInfo => {
390
+ :stage => 'Customer',
391
+ :lifetime_value => 24000,
392
+ :accountOwner => 'mary@contoso.com',
393
+ }
394
+ }
385
395
 
386
- user_models << user_model_A << user_model_B
387
- response = MoesifRack::MoesifMiddleware.new(@app, @options).update_users_batch(user_models)
396
+ # Campaign object is optional, but useful if you want to track ROI of acquisition channels
397
+ # See https://www.moesif.com/docs/api#users for campaign schema
398
+ campaign = CampaignModel.new()
399
+ campaign.utm_source = "google"
400
+ campaign.utm_medium = "cpc"
401
+ campaign.utm_campaign = "adwords"
402
+ campaign.utm_term = "api+tooling"
403
+ campaign.utm_content = "landing"
404
+
405
+ # Only user_id is required.
406
+ # metadata can be any custom object
407
+ user = UserModel.new()
408
+ user.user_id = "12345"
409
+ user.company_id = "67890" # If set, associate user with a company object
410
+ user.campaign = campaign
411
+ user.metadata = metadata
412
+
413
+ users << user
414
+
415
+ response = MoesifRack::MoesifMiddleware.new(@app, @options).update_users_batch(users)
388
416
  ```
389
417
 
390
418
  ## Update Company
391
419
 
392
- ### update_company method
393
- A method is attached to the moesif middleware object to update the company profile or metadata.
394
- The metadata field can be any custom data you want to set on the company. The `company_id` field is required.
420
+ ### Update a Single Company
421
+ Create or update a company profile in Moesif.
422
+ The metadata field can be any company demographic or other info you want to store.
423
+ Only the `company_id` field is required.
424
+ This method is a convenient helper that calls the Moesif API lib.
425
+ For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-a-company).
395
426
 
396
427
  ```ruby
397
- metadata = JSON.parse('{'\
398
- '"email": "testrubyapi@company.com",'\
399
- '"name": "ruby api company",'\
400
- '"custom": "testdata"'\
401
- '}')
428
+ metadata => {
429
+ :org_name => 'Acme, Inc',
430
+ :plan_name => 'Free',
431
+ :deal_stage => 'Lead',
432
+ :mrr => 24000,
433
+ :demographics => {
434
+ :alexa_ranking => 500000,
435
+ :employee_count => 47
436
+ }
437
+ }
402
438
 
403
- company_model = { "company_id" => "12345",
404
- "company_domain" => "acmeinc.com",
405
- "metadata" => metadata }
439
+ # Campaign object is optional, but useful if you want to track ROI of acquisition channels
440
+ # See https://www.moesif.com/docs/api#update-a-company for campaign schema
441
+ campaign = CampaignModel.new()
442
+ campaign.utm_source = "google"
443
+ campaign.utm_medium = "cpc"
444
+ campaign.utm_campaign = "adwords"
445
+ campaign.utm_term = "api+tooling"
446
+ campaign.utm_content = "landing"
447
+
448
+ # Only company_id is required.
449
+ # metadata can be any custom object
450
+ company = CompanyModel.new()
451
+ company.company_id = "67890"
452
+ company.company_domain = "acmeinc.com" # If domain is set, Moesif will enrich your profiles with publicly available info
453
+ company.campaign = campaign
454
+ company.metadata = metadata
406
455
 
407
456
  update_company = MoesifRack::MoesifMiddleware.new(@app, @options).update_company(company_model)
408
457
  ```
409
458
 
410
- ### update_companies_batch method
411
- A method is attached to the moesif middleware object to update the companies profile or metadata in batch.
412
- The metadata field can be any custom data you want to set on the company. The `company_id` field is required.
459
+ ### Update Companies in Batch
460
+ Similar to update_company, but used to update a list of companies in one batch.
461
+ Only the `company_id` field is required.
462
+ This method is a convenient helper that calls the Moesif API lib.
463
+ For details, visit the [Ruby API Reference](https://www.moesif.com/docs/api?ruby#update-companies-in-batch).
413
464
 
414
465
  ```ruby
415
466
  metadata = JSON.parse('{'\
@@ -418,18 +469,38 @@ metadata = JSON.parse('{'\
418
469
  '"custom": "testdata"'\
419
470
  '}')
420
471
 
421
- company_models = []
422
-
423
- company_model_A = { "company_id" => "12345",
424
- "company_domain" => "nowhere.com",
425
- "metadata" => metadata }
472
+ companies = []
426
473
 
427
- company_model_B = { "company_id" => "67890",
428
- "company_domain" => "acmeinc.com",
429
- "metadata" => metadata }
474
+ metadata => {
475
+ :org_name => 'Acme, Inc',
476
+ :plan_name => 'Free',
477
+ :deal_stage => 'Lead',
478
+ :mrr => 24000,
479
+ :demographics => {
480
+ :alexa_ranking => 500000,
481
+ :employee_count => 47
482
+ }
483
+ }
430
484
 
431
- company_models << company_model_A << company_model_B
432
- response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_batch(company_models)
485
+ # Campaign object is optional, but useful if you want to track ROI of acquisition channels
486
+ # See https://www.moesif.com/docs/api#update-a-company for campaign schema
487
+ campaign = CampaignModel.new()
488
+ campaign.utm_source = "google"
489
+ campaign.utm_medium = "cpc"
490
+ campaign.utm_campaign = "adwords"
491
+ campaign.utm_term = "api+tooling"
492
+ campaign.utm_content = "landing"
493
+
494
+ # Only company_id is required.
495
+ # metadata can be any custom object
496
+ company = CompanyModel.new()
497
+ company.company_id = "67890"
498
+ company.company_domain = "acmeinc.com" # If domain is set, Moesif will enrich your profiles with publicly available info
499
+ company.campaign = campaign
500
+ company.metadata = metadata
501
+
502
+ companies << company
503
+ response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_batch(companies)
433
504
  ```
434
505
 
435
506
  ## How to test
@@ -443,11 +514,13 @@ response = MoesifRack::MoesifMiddleware.new(@app, @options).update_companies_bat
443
514
 
444
515
  ## Example Code
445
516
 
446
- [Moesif Rack Example](https://github.com/Moesif/moesif-rack-example) is an example of Moesif Rack applied to an Rail application. Please check it out for reference.
517
+ [Moesif Rack Example with Rails](https://github.com/Moesif/moesif-rails-example) is an example of Moesif Rack applied to a Rails application.
518
+
519
+ [Moesif Rack Example](https://github.com/Moesif/moesif-rack-example) is an example of Moesif Rack applied to a Rack application.
447
520
 
448
521
  ## Other integrations
449
522
 
450
- To view more more documentation on integration options, please visit [the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).
523
+ To view more documentation on integration options, please visit [the Integration Options Documentation](https://www.moesif.com/docs/getting-started/integration-options/).
451
524
 
452
525
  [ico-built-for]: https://img.shields.io/badge/built%20for-rack-blue.svg
453
526
  [ico-version]: https://img.shields.io/gem/v/moesif_rack.svg
@@ -0,0 +1,121 @@
1
+ require 'moesif_api'
2
+ require 'json'
3
+ require 'time'
4
+ require 'zlib'
5
+ require 'stringio'
6
+
7
+ class AppConfig
8
+
9
+ def get_config(api_controller, debug)
10
+ # Get Application Config
11
+ begin
12
+ config_api_response = api_controller.get_app_config()
13
+ return config_api_response
14
+ rescue MoesifApi::APIException => e
15
+ if e.response_code.between?(401, 403)
16
+ puts 'Unauthorized access getting application configuration. Please check your Appplication Id.'
17
+ end
18
+ if debug
19
+ puts 'Error getting application configuration, with status code:'
20
+ puts e.response_code
21
+ end
22
+ end
23
+ end
24
+
25
+ def parse_configuration(config_api_response, debug)
26
+ # Parse configuration object and return Etag, sample rate and last updated time
27
+ begin
28
+ # Rails return gzipped compressed response body, so decompressing it and getting JSON response body
29
+ response_body = decompress_gzip_body(config_api_response, debug)
30
+
31
+ # Check if response body is not nil
32
+ if !response_body.nil? then
33
+ # Return Etag, sample rate and last updated time
34
+ return config_api_response.headers[:x_moesif_config_etag], response_body.fetch("sample_rate", 100), Time.now.utc
35
+ else
36
+ if debug
37
+ puts 'Response body is nil, assuming default behavior'
38
+ end
39
+ # Response body is nil, so assuming default behavior
40
+ return nil, 100, Time.now.utc
41
+ end
42
+ rescue => exception
43
+ if debug
44
+ puts 'Error while parsing the configuration object, assuming default behavior'
45
+ puts exception.to_s
46
+ end
47
+ # Assuming default behavior
48
+ return nil, 100, Time.now.utc
49
+ end
50
+ end
51
+
52
+ def get_sampling_percentage(config_api_response, user_id, company_id, debug)
53
+ # Get sampling percentage
54
+ begin
55
+ # Rails return gzipped compressed response body, so decompressing it and getting JSON response body
56
+ response_body = decompress_gzip_body(config_api_response, debug)
57
+
58
+ # Check if response body is not nil
59
+ if !response_body.nil? then
60
+
61
+ # Get user sample rate object
62
+ user_sample_rate = response_body.fetch('user_sample_rate', nil)
63
+
64
+ # Get company sample rate object
65
+ company_sample_rate = response_body.fetch('company_sample_rate', nil)
66
+
67
+ # Get sample rate for the user if exist
68
+ if !user_id.nil? && !user_sample_rate.nil? && user_sample_rate.key?(user_id)
69
+ return user_sample_rate.fetch(user_id)
70
+ end
71
+
72
+ # Get sample rate for the company if exist
73
+ if !company_id.nil? && !company_sample_rate.nil? && company_sample_rate.key?(company_id)
74
+ return company_sample_rate.fetch(company_id)
75
+ end
76
+
77
+ # Return sample rate
78
+ return response_body.fetch('sample_rate', 100)
79
+ else
80
+ if debug
81
+ puts 'Assuming default behavior as response body is nil - '
82
+ end
83
+ return 100
84
+ end
85
+ rescue => exception
86
+ if debug
87
+ puts 'Error while geting sampling percentage, assuming default behavior'
88
+ end
89
+ return 100
90
+ end
91
+ end
92
+
93
+ def decompress_gzip_body(config_api_response, debug)
94
+ # Decompress gzip response body
95
+ begin
96
+ # Check if the content-encoding header exist and is of type zip
97
+ if config_api_response.headers.key?(:content_encoding) && config_api_response.headers[:content_encoding].eql?( 'gzip' ) then
98
+
99
+ # Create a GZipReader object to read data
100
+ gzip_reader = Zlib::GzipReader.new(StringIO.new(config_api_response.raw_body.to_s))
101
+
102
+ # Read the body
103
+ uncompressed_string = gzip_reader.read
104
+
105
+ # Return the parsed body
106
+ return JSON.parse( uncompressed_string )
107
+ else
108
+ if debug
109
+ puts 'Content Encoding is of type other than gzip, returning nil'
110
+ end
111
+ return nil
112
+ end
113
+ rescue => exception
114
+ if debug
115
+ puts 'Error while decompressing the response body'
116
+ puts exception.to_s
117
+ end
118
+ return nil
119
+ end
120
+ end
121
+ end
@@ -3,6 +3,7 @@ require 'json'
3
3
  require 'time'
4
4
  require 'base64'
5
5
  require_relative './client_ip.rb'
6
+ require_relative './app_config.rb'
6
7
  require_relative './update_user.rb'
7
8
  require_relative './update_company.rb'
8
9
 
@@ -12,7 +13,7 @@ module MoesifRack
12
13
  def initialize app, options = {}
13
14
  @app = app
14
15
  if not options['application_id']
15
- raise 'application_id requird for Moesif Middleware'
16
+ raise 'application_id required for Moesif Middleware'
16
17
  end
17
18
  @api_client = MoesifApi::MoesifAPIClient.new(options['application_id'])
18
19
  @api_controller = @api_client.api
@@ -25,15 +26,27 @@ module MoesifRack
25
26
  @mask_data = options['mask_data']
26
27
  @skip = options['skip']
27
28
  @debug = options['debug']
29
+ @app_config = AppConfig.new
30
+ @config = @app_config.get_config(@api_controller, @debug)
31
+ @config_etag = nil
32
+ @sampling_percentage = 100
33
+ @last_updated_time = Time.now.utc
28
34
  @config_dict = Hash.new
29
35
  @disable_transaction_id = options['disable_transaction_id'] || false
30
36
  @log_body = options.fetch('log_body', true)
31
- @sampling_percentage = get_config(nil)
32
- if not @sampling_percentage.is_a? Numeric
33
- raise "Sampling Percentage should be a number"
37
+ begin
38
+ if !@config.nil?
39
+ @config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
40
+ end
41
+ rescue => exception
42
+ if @debug
43
+ puts 'Error while parsing application configuration on initialization'
44
+ puts exception.to_s
45
+ end
34
46
  end
35
47
  @capture_outoing_requests = options['capture_outoing_requests']
36
- if @capture_outoing_requests
48
+ @capture_outgoing_requests = options['capture_outgoing_requests']
49
+ if @capture_outoing_requests || @capture_outgoing_requests
37
50
  if @debug
38
51
  puts 'Start Capturing outgoing requests'
39
52
  end
@@ -42,35 +55,6 @@ module MoesifRack
42
55
  end
43
56
  end
44
57
 
45
- def get_config(cached_config_etag)
46
- sample_rate = 100
47
- begin
48
- # Calling the api
49
- config_api_response = @api_controller.get_app_config()
50
- # Fetch the response ETag
51
- response_config_etag = JSON.parse( config_api_response.to_json )["headers"]["x_moesif_config_etag"]
52
- # Remove ETag from the global dict if exist
53
- if !cached_config_etag.nil? && @config_dict.key?(cached_config_etag)
54
- @config_dict.delete(cached_config_etag)
55
- end
56
- # Fetch the response body
57
- @config_dict[response_config_etag] = JSON.parse(JSON.parse( config_api_response.to_json )["raw_body"])
58
- #
59
- app_config = @config_dict[response_config_etag]
60
- # Fetch the sample rate
61
- if !app_config.nil?
62
- sample_rate = app_config.fetch("sample_rate", 100)
63
- end
64
- # Set the last updated time
65
- @last_updated_time = Time.now.utc
66
- rescue
67
- # Set the last updated time
68
- @last_updated_time = Time.now.utc
69
- end
70
- # Return the sample rate
71
- return sample_rate
72
- end
73
-
74
58
  def update_user(user_profile)
75
59
  UserHelper.new.update_user(@api_controller, @debug, user_profile)
76
60
  end
@@ -194,6 +178,7 @@ module MoesifRack
194
178
  event_model = MoesifApi::EventModel.new()
195
179
  event_model.request = event_req
196
180
  event_model.response = event_rsp
181
+ event_model.direction = "Incoming"
197
182
 
198
183
  if @identify_user
199
184
  if @debug
@@ -236,13 +221,31 @@ module MoesifRack
236
221
  # Perform the API call through the SDK function
237
222
  begin
238
223
  @random_percentage = Random.rand(0.00..100.00)
224
+
225
+ begin
226
+ @sampling_percentage = @app_config.get_sampling_percentage(@config, event_model.user_id, event_model.company_id, @debug)
227
+ rescue => exception
228
+ if @debug
229
+ puts 'Error while getting sampling percentage, assuming default behavior'
230
+ puts exception.to_s
231
+ end
232
+ @sampling_percentage = 100
233
+ end
234
+
239
235
  if @sampling_percentage > @random_percentage
240
236
  event_api_response = @api_controller.create_event(event_model)
241
- cached_config_etag = @config_dict.keys[0]
242
237
  event_response_config_etag = event_api_response[:x_moesif_config_etag]
243
238
 
244
- if !event_response_config_etag.nil? && cached_config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 30
245
- @sampling_percentage = get_config(cached_config_etag)
239
+ if !event_response_config_etag.nil? && !@config_etag.nil? && @config_etag != event_response_config_etag && Time.now.utc > @last_updated_time + 300
240
+ begin
241
+ @config = @app_config.get_config(@api_controller, @debug)
242
+ @config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
243
+ rescue => exception
244
+ if @debug
245
+ puts 'Error while updating the application configuration'
246
+ puts exception.to_s
247
+ end
248
+ end
246
249
  end
247
250
  if @debug
248
251
  puts("Event successfully sent to Moesif")
@@ -102,6 +102,7 @@ module MoesifCaptureOutgoing
102
102
  event_model = MoesifApi::EventModel.new()
103
103
  event_model.request = event_req
104
104
  event_model.response = event_rsp
105
+ event_model.direction = "Outgoing"
105
106
 
106
107
  # Metadata for Outgoing Request
107
108
  if @get_metadata_outgoing
@@ -1,6 +1,7 @@
1
1
  require 'test/unit'
2
2
  require 'rack'
3
3
  require 'net/http'
4
+ require_relative '../lib/moesif_rack/app_config.rb'
4
5
  require_relative '../lib/moesif_rack'
5
6
 
6
7
  class MoesifRackTest < Test::Unit::TestCase
@@ -9,7 +10,7 @@ class MoesifRackTest < Test::Unit::TestCase
9
10
  @options = { 'application_id' => 'Your Moesif Application Id',
10
11
  'debug' => true,
11
12
  'disable_transaction_id' => true,
12
- 'capture_outoing_requests' => true,
13
+ 'capture_outgoing_requests' => true,
13
14
  'get_metadata' => Proc.new {|request, response|
14
15
  {
15
16
  'foo' => 'abc',
@@ -45,6 +46,7 @@ class MoesifRackTest < Test::Unit::TestCase
45
46
  }
46
47
  }
47
48
  @moesif_rack_app = MoesifRack::MoesifMiddleware.new(@app, @options)
49
+ @app_config = AppConfig.new
48
50
  end
49
51
 
50
52
  def test_capture_outgoing
@@ -67,10 +69,14 @@ class MoesifRackTest < Test::Unit::TestCase
67
69
  '"custom": "testdata"'\
68
70
  '}')
69
71
 
72
+ campaign_model = {"utm_source" => "Newsletter",
73
+ "utm_medium" => "Email"}
74
+
70
75
  user_model = { "user_id" => "12345",
71
76
  "company_id" => "67890",
72
77
  "modified_time" => Time.now.utc.iso8601,
73
- "metadata" => metadata }
78
+ "metadata" => metadata,
79
+ "campaign" => campaign_model}
74
80
 
75
81
  response = @moesif_rack_app.update_user(user_model)
76
82
  assert_equal response, nil
@@ -106,7 +112,11 @@ class MoesifRackTest < Test::Unit::TestCase
106
112
  end
107
113
 
108
114
  def test_get_config
109
- assert_operator 100, :>=, @moesif_rack_app.get_config(nil)
115
+ @api_client = MoesifApi::MoesifAPIClient.new(@options['application_id'])
116
+ @api_controller = @api_client.api
117
+ @config = @app_config.get_config(@api_controller, @debug)
118
+ @config_etag, @sampling_percentage, @last_updated_time = @app_config.parse_configuration(@config, @debug)
119
+ assert_operator 100, :>=, @sampling_percentage
110
120
  end
111
121
 
112
122
  def test_update_company
@@ -116,9 +126,13 @@ class MoesifRackTest < Test::Unit::TestCase
116
126
  '"custom": "testdata"'\
117
127
  '}')
118
128
 
129
+ campaign_model = {"utm_source" => "Adwords",
130
+ "utm_medium" => "Twitter"}
131
+
119
132
  company_model = { "company_id" => "12345",
120
133
  "company_domain" => "acmeinc.com",
121
- "metadata" => metadata }
134
+ "metadata" => metadata,
135
+ "campaign" => campaign_model }
122
136
 
123
137
  response = @moesif_rack_app.update_company(company_model)
124
138
  assert_equal response, nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moesif_rack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.5
4
+ version: 1.3.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Moesif, Inc
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-10-11 00:00:00.000000000 Z
12
+ date: 2019-12-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: test-unit
@@ -31,14 +31,14 @@ dependencies:
31
31
  requirements:
32
32
  - - "~>"
33
33
  - !ruby/object:Gem::Version
34
- version: 1.2.8
34
+ version: 1.2.10
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
39
  - - "~>"
40
40
  - !ruby/object:Gem::Version
41
- version: 1.2.8
41
+ version: 1.2.10
42
42
  description: Collection/Data Ingestion SDK for Rack (also Rails) Middleware / RoR
43
43
  email: xing@moesif.com
44
44
  executables: []
@@ -48,6 +48,7 @@ files:
48
48
  - LICENSE
49
49
  - README.md
50
50
  - lib/moesif_rack.rb
51
+ - lib/moesif_rack/app_config.rb
51
52
  - lib/moesif_rack/client_ip.rb
52
53
  - lib/moesif_rack/moesif_middleware.rb
53
54
  - lib/moesif_rack/update_company.rb