embulk-input-marketo 0.2.5 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: cd2aca4cc3202db0cc6da4d33a1d564ad601ec15
4
- data.tar.gz: c0b2a2bec618d140967d54f054c6efe0c40e25ee
3
+ metadata.gz: 803b16c2edca4432ffcb1f32e9914d944b3747dd
4
+ data.tar.gz: bb28951330b3b3ac1a8d3bf7a3e81541915268e2
5
5
  SHA512:
6
- metadata.gz: 0b2aeaf51b0d648b8b0ea0c14f43caa6df2931bc732ea47d65d5829e99cb3378ccd12a634ffb579b643a30d629554559a449fbc30b994fb594e29d8c9cd735fe
7
- data.tar.gz: efb4857536cd3050527a1eb9f13a040cdc91268fe7569bc3a3006fd93abf3855876078b06ba555902eb704b1abc1aa54e26069ea963310c26f00c31ce14a5a1b
6
+ metadata.gz: 53f1320084a90a824af96b5205ae05f3d8596e79169abc7b15282c67d359ca8c26b8c1e433dcab5ff7b678ba1b239347b7ebd9eda547eb79bbde6ca931227aed
7
+ data.tar.gz: e6a1e61e3a7d4d0b875b0e704298d7e96d0e1ab395125e461ef704ef069267ac407b515538e2576dbf7ada5420b2f8b473a5d04337f5600648dd5e3649d2c7f6
@@ -1,3 +1,9 @@
1
+ ## 0.3.0 - 2015-09-30
2
+
3
+ This version breaks backword compatibility of marketo/activity_log. Please check README.md to modify your config.
4
+
5
+ * [enhancement] Also activity_log uses from_datetime/to_datetime same as lead [#39](https://github.com/treasure-data/embulk-input-marketo/pull/39)
6
+
1
7
  ## 0.2.5 - 2015-09-28
2
8
 
3
9
  * [fixed] lead: Fix the bug when `from_datetime` and `to_datetime` are same [#37](https://github.com/treasure-data/embulk-input-marketo/pull/37)
data/README.md CHANGED
@@ -1,8 +1,7 @@
1
1
  [![Build Status](https://travis-ci.org/treasure-data/embulk-input-marketo.svg?branch=master)](https://travis-ci.org/treasure-data/embulk-input-marketo)
2
-
3
2
  [![Code Climate](https://codeclimate.com/github/treasure-data/embulk-input-marketo/badges/gpa.svg)](https://codeclimate.com/github/treasure-data/embulk-input-marketo)
4
-
5
3
  [![Test Coverage](https://codeclimate.com/github/treasure-data/embulk-input-marketo/badges/coverage.svg)](https://codeclimate.com/github/treasure-data/embulk-input-marketo/coverage)
4
+ [![Gem Version](https://badge.fury.io/rb/embulk-input-marketo.svg)](http://badge.fury.io/rb/embulk-input-marketo)
6
5
 
7
6
  # Marketo input plugin for Embulk
8
7
 
@@ -51,7 +50,8 @@ Below parameters are shown in "Admin" > "Web Services" page in Marketo.
51
50
  - **wsdl** SOAP endpoint URL for your account (string, default: endpoint + "?WSDL")
52
51
  - **user_id** Your user id (string, reqiured)
53
52
  - **encryption_key** Your encryption key (string, reqiured)
54
- - **last_updated_at** Limit datetime that a lead has been updated (this plugin fetches leads updated after this datetime) (string, required)
53
+ - **from_datetime** Fetch activity_logs since this time (string, required)
54
+ - **to_datetime** Fetch activity_logs until this time (string, default: Time.now)
55
55
 
56
56
  ### Selecting plugin type
57
57
 
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |spec|
2
2
  spec.name = "embulk-input-marketo"
3
- spec.version = "0.2.5"
3
+ spec.version = "0.3.0"
4
4
  spec.authors = ["uu59", "yoshihara"]
5
5
  spec.summary = "Marketo input plugin for Embulk"
6
6
  spec.description = "Loads records from Marketo."
@@ -13,6 +13,7 @@ Gem::Specification.new do |spec|
13
13
  spec.require_paths = ["lib"]
14
14
 
15
15
  spec.add_dependency 'savon', ['~> 2.11.1']
16
+ spec.add_dependency 'httpclient'
16
17
  spec.add_development_dependency 'embulk', [">= 0.6.13", "< 1.0"]
17
18
  spec.add_development_dependency 'bundler', ['~> 1.0']
18
19
  spec.add_development_dependency 'rake', ['>= 10.0']
@@ -10,11 +10,38 @@ module Embulk
10
10
  :activity_log
11
11
  end
12
12
 
13
+ def self.transaction(config, &control)
14
+ endpoint_url = config.param(:endpoint, :string)
15
+
16
+ range = format_range(config)
17
+
18
+ task = {
19
+ endpoint_url: endpoint_url,
20
+ wsdl_url: config.param(:wsdl, :string, default: "#{endpoint_url}?WSDL"),
21
+ user_id: config.param(:user_id, :string),
22
+ encryption_key: config.param(:encryption_key, :string),
23
+ from_datetime: range[:from],
24
+ to_datetime: range[:to],
25
+ columns: config.param(:columns, :array)
26
+ }
27
+
28
+ columns = []
29
+
30
+ task[:columns].each do |column|
31
+ name = column["name"]
32
+ type = column["type"].to_sym
33
+
34
+ columns << Column.new(nil, name, type, column["format"])
35
+ end
36
+
37
+ resume(task, columns, 1, &control)
38
+ end
39
+
13
40
  def self.guess(config)
14
41
  client = soap_client(config)
15
- last_updated_at = config.param(:last_updated_at, :string)
42
+ range = format_range(config)
16
43
 
17
- schema = client.metadata(last_updated_at, batch_size: PREVIEW_COUNT)
44
+ schema = client.metadata(range[:from], batch_size: PREVIEW_COUNT)
18
45
  columns = schema.map do |c|
19
46
  column = {name: c.name, type: c.type}
20
47
  column[:format] = c.format if c.format
@@ -33,7 +60,7 @@ module Embulk
33
60
 
34
61
  count = 0
35
62
 
36
- last_updated_at = @soap.each(@last_updated_at, batch_size: batch_size) do |activity_log|
63
+ last_updated_at = @soap.each(task[:from_datetime], batch_size: batch_size, to: task[:to_datetime]) do |activity_log|
37
64
  values = @columns.map do |column|
38
65
  name = column["name"].to_s
39
66
  value = activity_log[name]
@@ -60,7 +87,7 @@ module Embulk
60
87
 
61
88
  commit_report = {}
62
89
  if !preview? && last_updated_at
63
- commit_report = {last_updated_at: last_updated_at}
90
+ commit_report = {from_datetime: last_updated_at}
64
91
  end
65
92
 
66
93
  return commit_report
@@ -13,30 +13,6 @@ module Embulk
13
13
  raise NotImplementedError
14
14
  end
15
15
 
16
- def self.transaction(config, &control)
17
- endpoint_url = config.param(:endpoint, :string)
18
-
19
- task = {
20
- endpoint_url: endpoint_url,
21
- wsdl_url: config.param(:wsdl, :string, default: "#{endpoint_url}?WSDL"),
22
- user_id: config.param(:user_id, :string),
23
- encryption_key: config.param(:encryption_key, :string),
24
- last_updated_at: config.param(:last_updated_at, :string),
25
- columns: config.param(:columns, :array)
26
- }
27
-
28
- columns = []
29
-
30
- task[:columns].each do |column|
31
- name = column["name"]
32
- type = column["type"].to_sym
33
-
34
- columns << Column.new(nil, name, type, column["format"])
35
- end
36
-
37
- resume(task, columns, 1, &control)
38
- end
39
-
40
16
  def self.resume(task, columns, count, &control)
41
17
  commit_reports = yield(task, columns, count)
42
18
 
@@ -80,6 +56,33 @@ module Embulk
80
56
  def target
81
57
  self.class.target
82
58
  end
59
+
60
+ def self.format_range(config)
61
+ if config.param(:last_updated_at, :string, default: nil)
62
+ Embulk.logger.warn "config: last_updated_at is deprecated. Use from_datetime/to_datetime"
63
+ end
64
+
65
+ from_datetime = config.param(:from_datetime, :string)
66
+ to_datetime = config.param(:to_datetime, :string, default: Time.now.to_s)
67
+
68
+ # check from/to format to parse
69
+ begin
70
+ Time.parse(from_datetime)
71
+ Time.parse(to_datetime)
72
+ rescue => e
73
+ # possibly Time.parse fail
74
+ raise ConfigError, e.message
75
+ end
76
+
77
+ if Time.parse(from_datetime) > Time.parse(to_datetime)
78
+ raise ConfigError, "config: from_datetime '#{from_datetime}' is later than '#{to_datetime}'."
79
+ end
80
+
81
+ {
82
+ from: from_datetime,
83
+ to: to_datetime,
84
+ }
85
+ end
83
86
  end
84
87
  end
85
88
  end
@@ -18,8 +18,7 @@ module Embulk
18
18
  def each(last_updated_at, options={}, &block)
19
19
  response = fetch_by_last_updated_at(last_updated_at, options, &block)
20
20
  while response[:remaining_count] > 0 do
21
- offset = response[:offset]
22
- response = fetch_by_offset(offset, options, &block)
21
+ response = fetch_by_last_updated_at(last_updated_at, options.merge(offset: response[:offset]), &block)
23
22
  end
24
23
 
25
24
  response[:last_updated_at]
@@ -31,28 +30,26 @@ module Embulk
31
30
  last_updated_at = last_updated_at.to_s
32
31
  last_updated_at = Time.parse(last_updated_at).iso8601
33
32
 
34
- request = {
35
- start_position: {
36
- oldest_created_at: last_updated_at,
37
- },
38
- }
39
-
40
- fetch(request, options, &block)
41
- end
33
+ to =
34
+ if options[:to]
35
+ Time.parse(options[:to]).iso8601
36
+ else
37
+ Time.now.iso8601
38
+ end
42
39
 
43
- def fetch_by_offset(offset, options={}, &block)
44
40
  request = {
45
41
  start_position: {
46
- offset: offset,
42
+ oldest_created_at: last_updated_at,
43
+ latest_created_at: to,
47
44
  },
45
+ batch_size: options[:batch_size] || 100
48
46
  }
47
+ request[:start_position][:offset] = options[:offset] if options[:offset]
49
48
 
50
49
  fetch(request, options, &block)
51
50
  end
52
51
 
53
52
  def fetch(request, options={}, &block)
54
- request[:batch_size] = options[:batch_size] || 100
55
-
56
53
  response = savon_call(:get_lead_changes, message: request)
57
54
  remaining = response.body[:success_get_lead_changes][:result][:remaining_count].to_i
58
55
  Embulk.logger.info "Remaining records: #{remaining}"
@@ -1,4 +1,5 @@
1
1
  require "savon"
2
+ require "httpclient" # net/http can't verify cert correctly
2
3
 
3
4
  module Embulk
4
5
  module Input
@@ -8,6 +8,64 @@ module Embulk
8
8
  class ActivityLogTest < Test::Unit::TestCase
9
9
  include ActivityLogFixtures
10
10
 
11
+ class TransactionTest < self
12
+ def test_generate_task
13
+ control = proc {} # dummy
14
+ columns = task[:columns].map do |col|
15
+ Column.new(nil, col["name"], col["type"].to_sym, col["format"])
16
+ end
17
+
18
+ mock(ActivityLog).resume(task, columns, 1, &control)
19
+ ActivityLog.transaction(config, &control)
20
+ end
21
+
22
+ private
23
+
24
+ def settings
25
+ {
26
+ endpoint: "https://marketo.example.com",
27
+ wsdl: "https://marketo.example.com/?wsdl",
28
+ user_id: "user_id",
29
+ encryption_key: "TOPSECRET",
30
+ from_datetime: from_datetime,
31
+ to_datetime: to_datetime,
32
+ columns: [
33
+ {"name" => :id, "type" => :long},
34
+ {"name" => :activity_date_time, "type" => :timestamp, "format" => "%Y-%m-%dT%H:%M:%S%z"},
35
+ {"name" => :activity_type, "type" => :string},
36
+ {"name" => :mktg_asset_name, "type" => :string},
37
+ {"name" => :mkt_person_id, "type" => :long},
38
+ {"name" => "Attribute Name", "type" => :string},
39
+ {"name" => "Old Value", "type" => :string},
40
+ ]
41
+ }
42
+ end
43
+
44
+ def config
45
+ DataSource[settings.to_a]
46
+ end
47
+
48
+ def task
49
+ {
50
+ endpoint_url: "https://marketo.example.com",
51
+ wsdl_url: "https://marketo.example.com/?wsdl",
52
+ user_id: "user_id",
53
+ encryption_key: "TOPSECRET",
54
+ from_datetime: from_datetime,
55
+ to_datetime: to_datetime,
56
+ columns: [
57
+ {"name" => :id, "type" => :long},
58
+ {"name" => :activity_date_time, "type" => :timestamp, "format" => "%Y-%m-%dT%H:%M:%S%z"},
59
+ {"name" => :activity_type, "type" => :string},
60
+ {"name" => :mktg_asset_name, "type" => :string},
61
+ {"name" => :mkt_person_id, "type" => :long},
62
+ {"name" => "Attribute Name", "type" => :string},
63
+ {"name" => "Old Value", "type" => :string},
64
+ ]
65
+ }
66
+ end
67
+ end
68
+
11
69
  def test_target
12
70
  assert_equal(:activity_log, ActivityLog.target)
13
71
  end
@@ -22,7 +80,7 @@ module Embulk
22
80
  end
23
81
 
24
82
  def test_include_metadata
25
- stub(@soap).metadata(last_updated_at, batch_size: ActivityLog::PREVIEW_COUNT) { Guess::SchemaGuess.from_hash_records(records) }
83
+ stub(@soap).metadata(from_datetime, batch_size: ActivityLog::PREVIEW_COUNT) { Guess::SchemaGuess.from_hash_records(records) }
26
84
 
27
85
  assert_equal(
28
86
  {"columns" => expected_guessed_columns},
@@ -166,7 +224,8 @@ module Embulk
166
224
  def request
167
225
  {
168
226
  start_position: {
169
- oldest_created_at: Time.parse(last_updated_at).iso8601,
227
+ oldest_created_at: Time.parse(from_datetime).iso8601,
228
+ latest_created_at: Time.parse(to_datetime).iso8601,
170
229
  },
171
230
  batch_size: 100
172
231
  }
@@ -175,6 +234,8 @@ module Embulk
175
234
  def offset_request
176
235
  {
177
236
  start_position: {
237
+ oldest_created_at: Time.parse(from_datetime).iso8601,
238
+ latest_created_at: Time.parse(to_datetime).iso8601,
178
239
  offset: "offset"
179
240
  },
180
241
  batch_size: 100
@@ -185,7 +246,7 @@ module Embulk
185
246
  def preview_request
186
247
  {
187
248
  start_position: {
188
- oldest_created_at: Time.parse(last_updated_at).iso8601,
249
+ oldest_created_at: Time.parse(from_datetime).iso8601,
189
250
  },
190
251
  batch_size: ActivityLog::PREVIEW_COUNT
191
252
  }
@@ -199,7 +260,8 @@ module Embulk
199
260
  wsdl: "https://marketo.example.com/?wsdl",
200
261
  user_id: "user_id",
201
262
  encryption_key: "TOPSECRET",
202
- last_updated_at: last_updated_at,
263
+ from_datetime: from_datetime,
264
+ to_datetime: to_datetime,
203
265
  }
204
266
  end
205
267
 
@@ -213,7 +275,8 @@ module Embulk
213
275
  wsdl_url: "https://marketo.example.com/?wsdl",
214
276
  user_id: "user_id",
215
277
  encryption_key: "TOPSECRET",
216
- last_updated_at: last_updated_at,
278
+ from_datetime: from_datetime,
279
+ to_datetime: to_datetime,
217
280
  columns: [
218
281
  {"name" => :id, "type" => :long},
219
282
  {"name" => :activity_date_time, "type" => :timestamp, "format" => "%Y-%m-%dT%H:%M:%S%z"},
@@ -226,9 +289,13 @@ module Embulk
226
289
  }
227
290
  end
228
291
 
229
- def last_updated_at
292
+ def from_datetime
230
293
  "2015-07-01 00:00:00+00:00"
231
294
  end
295
+
296
+ def to_datetime
297
+ "2015-11-01 00:00:00+00:00"
298
+ end
232
299
  end
233
300
  end
234
301
  end
@@ -11,16 +11,6 @@ module Embulk
11
11
  end
12
12
  end
13
13
 
14
- def test_transaction
15
- control = proc {} # dummy
16
- columns = task[:columns].map do |col|
17
- Column.new(nil, col["name"], col["type"].to_sym)
18
- end
19
-
20
- mock(Base).resume(task, columns, 1, &control)
21
- Base.transaction(config, &control)
22
- end
23
-
24
14
  def test_resume
25
15
  next_config_diff = {last_updated_at: last_updated_at}
26
16
  control = proc { [next_config_diff] } # In actual, embulk prepares control block returning Array.
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-marketo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - uu59
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-09-28 00:00:00.000000000 Z
12
+ date: 2015-09-30 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  requirement: !ruby/object:Gem::Requirement
@@ -25,6 +25,20 @@ dependencies:
25
25
  - - ~>
26
26
  - !ruby/object:Gem::Version
27
27
  version: 2.11.1
28
+ - !ruby/object:Gem::Dependency
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ name: httpclient
35
+ prerelease: false
36
+ type: :runtime
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
28
42
  - !ruby/object:Gem::Dependency
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements: