embulk-input-google_analytics 0.1.17 → 0.1.18.alpha

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
  SHA1:
3
- metadata.gz: 8c0c86f1ec128421575f09495f1650bc36b9003e
4
- data.tar.gz: 356d14ca378502fa5a3c7d8781162f318ac62797
3
+ metadata.gz: 840c722b01ba3cf337f7b5e405e8b6b07676810b
4
+ data.tar.gz: 9416098303f34773cf3df1329a8eaf84fe4594b2
5
5
  SHA512:
6
- metadata.gz: 2030bd41d01b4d67e5a694512af6d5cfd4e153570f705e9584fc9d31cb5d7bb439d82726143e6929ffcdc3fb15a1acd2d302d9411a9f3434bf347019b05fc8c7
7
- data.tar.gz: d98bf69f0cefa62bb1058104300bba29a1ff527277d562921529f9ce7108bffc4b25fc1a1b8a6920d5f7edbd0f1c1571793c970f862105c91e14c391a0123a01
6
+ metadata.gz: 736e069eb795ba331c2125df44cb5cc48525f8bb4a44f43e62bb1b0b27c2b1affbd9e8e76fd76dfeeaeb8eaa64b5b9e91cde98254d4a3c90600fb30c7534ac64
7
+ data.tar.gz: 61a3515ba0cd0c28832d39d215b5619e3e62799164155c28ace126f773c8c4c08398e040b5424d38fb775fd08414d0af20833e8c6d5d4ab038ee5cf1373d459e
@@ -1,7 +1,7 @@
1
1
 
2
2
  Gem::Specification.new do |spec|
3
3
  spec.name = "embulk-input-google_analytics"
4
- spec.version = "0.1.17"
4
+ spec.version = "0.1.18.alpha"
5
5
  spec.authors = ["uu59"]
6
6
  spec.summary = "Google Analytics input plugin for Embulk"
7
7
  spec.description = "Loads records from Google Analytics."
@@ -27,5 +27,6 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency 'simplecov'
28
28
  spec.add_development_dependency "codeclimate-test-reporter"
29
29
  spec.add_development_dependency "pry"
30
+ spec.add_development_dependency "pry-debugger-jruby"
30
31
  spec.add_development_dependency "gem_release_helper", "~> 1.0"
31
32
  end
@@ -208,10 +208,22 @@ module Embulk
208
208
 
209
209
  def auth
210
210
  retryer.with_retry do
211
- Google::Auth::ServiceAccountCredentials.make_creds(
212
- json_key_io: StringIO.new(task["json_key_content"]),
213
- scope: "https://www.googleapis.com/auth/analytics.readonly"
214
- )
211
+ case task['auth_method']
212
+ when Plugin::AUTH_TYPE_JSON_KEY
213
+ Google::Auth::ServiceAccountCredentials.make_creds(
214
+ json_key_io: StringIO.new(task["json_key_content"]),
215
+ scope: "https://www.googleapis.com/auth/analytics.readonly"
216
+ )
217
+ when Plugin::AUTH_TYPE_REFRESH_TOKEN
218
+ Google::Auth::UserRefreshCredentials.new(
219
+ 'token_credential_uri': Google::Auth::UserRefreshCredentials::TOKEN_CRED_URI,
220
+ 'client_id': task['client_id'],
221
+ 'client_secret': task['client_secret'],
222
+ 'refresh_token': task['refresh_token']
223
+ )
224
+ else
225
+ raise Embulk::ConfigError.new("Unknown Authentication method: '#{task['auth_method']}'.")
226
+ end
215
227
  end
216
228
  rescue Google::Apis::AuthorizationError => e
217
229
  raise ConfigError.new(e.message)
@@ -3,6 +3,8 @@ module Embulk
3
3
  module GoogleAnalytics
4
4
  class Plugin < InputPlugin
5
5
  ::Embulk::Plugin.register_input("google_analytics", self)
6
+ AUTH_TYPE_JSON_KEY = 'json_key'.freeze
7
+ AUTH_TYPE_REFRESH_TOKEN = 'refresh_token'.freeze
6
8
 
7
9
  # https://developers.google.com/analytics/devguides/reporting/core/dimsmets
8
10
 
@@ -11,6 +13,15 @@ module Embulk
11
13
  unless %w(ga:date ga:dateHour).include?(task["time_series"])
12
14
  raise ConfigError.new("Unknown time_series '#{task["time_series"]}'. Use 'ga:dateHour' or 'ga:date'")
13
15
  end
16
+
17
+ raise ConfigError.new("Unknown Authentication method '#{task['auth_method']}'.") unless task['auth_method']
18
+
19
+ if task['auth_method'] == Plugin::AUTH_TYPE_REFRESH_TOKEN
20
+ unless task['client_id'] && task['client_secret'] && task['refresh_token']
21
+ raise ConfigError.new("client_id, client_secret and refresh_token are required when using Oauth authentication")
22
+ end
23
+ end
24
+
14
25
  columns_list = Client.new(task).get_columns_list
15
26
 
16
27
  columns = columns_from_task(task).map do |col_name|
@@ -53,8 +64,16 @@ module Embulk
53
64
  end
54
65
 
55
66
  def self.task_from_config(config)
56
- json_key_content = config.param("json_key_content", :string)
57
- {
67
+ refresh_token = config.param('refresh_token', :string, default: nil)
68
+ json_key_content = config.param("json_key_content", :string, default: nil)
69
+
70
+ auth_method = Plugin::AUTH_TYPE_REFRESH_TOKEN if refresh_token
71
+ auth_method = Plugin::AUTH_TYPE_JSON_KEY if json_key_content && auth_method == nil
72
+ {
73
+ "auth_method" => auth_method,
74
+ "client_id" => config.param("client_id", :string, default: nil),
75
+ "client_secret" => config.param("client_secret", :string, default: nil),
76
+ "refresh_token" => refresh_token,
58
77
  "json_key_content" => json_key_content,
59
78
  "view_id" => config.param("view_id", :string),
60
79
  "dimensions" => config.param("dimensions", :array, default: []),
@@ -98,7 +117,7 @@ module Embulk
98
117
  client = Client.new(task, preview?)
99
118
  columns = self.class.columns_from_task(task) + ["view_id"]
100
119
 
101
- last_record_time = task["last_record_time"] ? Time.parse(task["last_record_time"]) : nil
120
+ last_record_time = task['incremental'] && task["last_record_time"] ? Time.parse(task["last_record_time"]) : nil
102
121
 
103
122
  latest_time_series = nil
104
123
  skip_counter, total_counter = 0, 0
@@ -283,6 +283,60 @@ module Embulk
283
283
  end
284
284
  end
285
285
 
286
+ sub_test_case "oauth_refresh_token" do
287
+ setup do
288
+ conf = valid_config_oauth["in"]
289
+ mute_logger
290
+ @client = Client.new(task(embulk_config(conf)))
291
+ end
292
+
293
+ sub_test_case "retry refresh token" do
294
+ def should_retry
295
+ mock(Google::Auth::UserRefreshCredentials).new(anything).times(retryer.config.limit + 1) { raise error }
296
+ assert_raise do
297
+ @client.auth
298
+ end
299
+ end
300
+
301
+ def should_not_retry
302
+ mock(Google::Auth::UserRefreshCredentials).new(anything).times(1) { raise error }
303
+ assert_raise do
304
+ @client.auth
305
+ end
306
+ end
307
+
308
+ sub_test_case "Server respones error (5xx)" do
309
+ def error
310
+ Google::Apis::ServerError.new("error")
311
+ end
312
+
313
+ test "should retry refresh token" do
314
+ should_retry
315
+ end
316
+ end
317
+
318
+ sub_test_case "Refresh token reach Rate Limit" do
319
+ def error
320
+ Google::Apis::RateLimitError.new("error")
321
+ end
322
+
323
+ test "should retry refresh token" do
324
+ should_retry
325
+ end
326
+ end
327
+
328
+ sub_test_case "Refresh token Error" do
329
+ def error
330
+ Google::Apis::AuthorizationError.new("error")
331
+ end
332
+
333
+ test "should not retry" do
334
+ should_not_retry
335
+ end
336
+ end
337
+ end
338
+ end
339
+
286
340
  sub_test_case "too_early_data?" do
287
341
  def stub_timezone(client)
288
342
  stub(client).get_profile { {timezone: "America/Los_Angeles" } }
@@ -412,6 +466,10 @@ module Embulk
412
466
  fixture_load("valid.yml")
413
467
  end
414
468
 
469
+ def valid_config_oauth
470
+ fixture_load("valid_refresh_token.yml")
471
+ end
472
+
415
473
  def embulk_config(hash)
416
474
  Embulk::DataSource.new(hash)
417
475
  end
@@ -75,6 +75,46 @@ module Embulk
75
75
  end
76
76
  end
77
77
 
78
+ test "missing client_id params for oauth" do
79
+ conf = valid_config_oauth["in"]
80
+ conf.delete("client_id")
81
+ assert_raise(Embulk::ConfigError.new(oauth_expect_message)) do
82
+ Plugin.transaction(embulk_config(conf))
83
+ end
84
+ end
85
+
86
+ test "missing client_secret params for oauth" do
87
+ conf = valid_config_oauth["in"]
88
+ conf.delete('client_secret')
89
+ assert_raise(Embulk::ConfigError.new(oauth_expect_message)) do
90
+ Plugin.transaction(embulk_config(conf))
91
+ end
92
+ end
93
+
94
+ test "missing refresh_token params for oauth" do
95
+ conf = valid_config_oauth["in"]
96
+ conf.delete("refresh_token")
97
+ assert_raise(Embulk::ConfigError.new(unknown_auth_method_message)) do
98
+ Plugin.transaction(embulk_config(conf))
99
+ end
100
+ end
101
+
102
+ test "missing json_key_content params for oauth" do
103
+ conf = valid_config["in"]
104
+ conf.delete("json_key_content")
105
+ assert_raise(Embulk::ConfigError.new(unknown_auth_method_message)) do
106
+ Plugin.transaction(embulk_config(conf))
107
+ end
108
+ end
109
+
110
+ def unknown_auth_method_message
111
+ "Unknown Authentication method ''."
112
+ end
113
+
114
+ def oauth_expect_message
115
+ "client_id, client_secret and refresh_token are required when using Oauth authentication"
116
+ end
117
+
78
118
  def unknown_col_name
79
119
  "ga:foooooo"
80
120
  end
@@ -162,12 +202,14 @@ module Embulk
162
202
 
163
203
  sub_test_case "last_record_time option" do
164
204
  setup do
205
+ stub(Plugin).calculate_next_times { {} }
165
206
  Time.zone = "America/Los_Angeles"
166
207
  @last_record_time = Time.zone.parse("2016-06-01 12:00:00").to_time
167
208
 
168
209
  conf = valid_config["in"]
169
210
  conf["time_series"] = time_series
170
211
  conf["last_record_time"] = @last_record_time.strftime("%Y-%m-%d %H:%M:%S %z")
212
+ conf['incremental'] = true
171
213
  @plugin = Plugin.new(embulk_config(conf), nil, nil, @page_builder)
172
214
  end
173
215
 
@@ -182,6 +224,7 @@ module Embulk
182
224
  }
183
225
  block.call row
184
226
  end
227
+ stub(klass).get_profile { {timezone: "America/Los_Angeles" } }
185
228
  end
186
229
 
187
230
  mock(@page_builder).add.never
@@ -219,12 +262,15 @@ module Embulk
219
262
 
220
263
  sub_test_case "last_record_time option" do
221
264
  setup do
265
+ stub(Plugin).calculate_next_times { {} }
222
266
  Time.zone = "America/Los_Angeles"
223
267
  @last_record_time = Time.zone.parse("2016-06-01 12:00:00").to_time
224
268
 
225
269
  conf = valid_config["in"]
226
270
  conf["time_series"] = time_series
227
271
  conf["last_record_time"] = @last_record_time.strftime("%Y-%m-%d %H:%M:%S %z")
272
+ conf['incremental'] = true
273
+
228
274
  @plugin = Plugin.new(embulk_config(conf), nil, nil, @page_builder)
229
275
  end
230
276
 
@@ -239,6 +285,7 @@ module Embulk
239
285
  }
240
286
  block.call row
241
287
  end
288
+ stub(klass).get_profile { {timezone: "America/Los_Angeles" } }
242
289
  end
243
290
 
244
291
  mock(@page_builder).add.never
@@ -250,6 +297,39 @@ module Embulk
250
297
  end
251
298
  end
252
299
 
300
+ sub_test_case "run non-incremental" do
301
+ sub_test_case " should be added to page_builder" do
302
+ setup do
303
+ Time.zone = "America/Los_Angeles"
304
+ @last_record_time = Time.zone.parse("2016-06-01 12:00:00").to_time
305
+
306
+ conf = valid_config["in"]
307
+ conf["time_series"] = "ga:date"
308
+ conf["last_record_time"] = @last_record_time.strftime("%Y-%m-%d %H:%M:%S %z")
309
+ conf['incremental'] = false
310
+ @plugin = Plugin.new(embulk_config(conf), nil, nil, @page_builder)
311
+ end
312
+
313
+ test "should allow record to be added to page_builder" do
314
+ any_instance_of(Client) do |klass|
315
+ stub(klass).each_report_row do |block|
316
+ row = {
317
+ "ga:date" => @last_record_time,
318
+ "ga:browser" => "wget",
319
+ "ga:visits" => 3,
320
+ "ga:pageviews" => 4,
321
+ }
322
+ block.call row
323
+ end
324
+ end
325
+
326
+ mock(@page_builder).add(anything).at_least(1)
327
+ mock(@page_builder).finish
328
+ @plugin.run
329
+ end
330
+ end
331
+ end
332
+
253
333
  sub_test_case "canonicalize_column_name" do
254
334
  data do
255
335
  [
@@ -457,6 +537,10 @@ module Embulk
457
537
  def embulk_config(hash)
458
538
  Embulk::DataSource.new(hash)
459
539
  end
540
+
541
+ def valid_config_oauth
542
+ fixture_load("valid_refresh_token.yml")
543
+ end
460
544
  end
461
545
  end
462
546
  end
@@ -0,0 +1,18 @@
1
+ in:
2
+ type: google_analytics
3
+ refresh_token: "your_refresh_token"
4
+ client_id: "your_client_id_here"
5
+ client_secret: "your_client_secret_here"
6
+ view_id: 101111111
7
+ time_series: "ga:dateHour"
8
+
9
+ dimensions:
10
+ - "ga:browser"
11
+ metrics:
12
+ - "ga:visits"
13
+ - "ga:pageviews"
14
+ retry_limit: 2
15
+ retry_initial_wait_sec: 0
16
+
17
+ out:
18
+ type: stdout
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-google_analytics
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.17
4
+ version: 0.1.18.alpha
5
5
  platform: ruby
6
6
  authors:
7
7
  - uu59
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-16 00:00:00.000000000 Z
11
+ date: 2018-05-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -192,6 +192,20 @@ dependencies:
192
192
  - - ">="
193
193
  - !ruby/object:Gem::Version
194
194
  version: '0'
195
+ - !ruby/object:Gem::Dependency
196
+ requirement: !ruby/object:Gem::Requirement
197
+ requirements:
198
+ - - ">="
199
+ - !ruby/object:Gem::Version
200
+ version: '0'
201
+ name: pry-debugger-jruby
202
+ prerelease: false
203
+ type: :development
204
+ version_requirements: !ruby/object:Gem::Requirement
205
+ requirements:
206
+ - - ">="
207
+ - !ruby/object:Gem::Version
208
+ version: '0'
195
209
  - !ruby/object:Gem::Dependency
196
210
  requirement: !ruby/object:Gem::Requirement
197
211
  requirements:
@@ -231,6 +245,7 @@ files:
231
245
  - test/fixture_helper.rb
232
246
  - test/fixtures/reports.json
233
247
  - test/fixtures/valid.yml
248
+ - test/fixtures/valid_refresh_token.yml
234
249
  - test/override_assert_raise.rb
235
250
  - test/run-test.rb
236
251
  homepage: https://github.com/treasure-data/embulk-input-google_analytics
@@ -248,9 +263,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
248
263
  version: '0'
249
264
  required_rubygems_version: !ruby/object:Gem::Requirement
250
265
  requirements:
251
- - - ">="
266
+ - - ">"
252
267
  - !ruby/object:Gem::Version
253
- version: '0'
268
+ version: 1.3.1
254
269
  requirements: []
255
270
  rubyforge_project:
256
271
  rubygems_version: 2.6.6
@@ -263,5 +278,6 @@ test_files:
263
278
  - test/fixture_helper.rb
264
279
  - test/fixtures/reports.json
265
280
  - test/fixtures/valid.yml
281
+ - test/fixtures/valid_refresh_token.yml
266
282
  - test/override_assert_raise.rb
267
283
  - test/run-test.rb