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 +4 -4
- data/CHANGELOG.md +6 -0
- data/README.md +3 -3
- data/embulk-input-marketo.gemspec +2 -1
- data/lib/embulk/input/marketo/activity_log.rb +31 -4
- data/lib/embulk/input/marketo/base.rb +27 -24
- data/lib/embulk/input/marketo_api/soap/activity_log.rb +11 -14
- data/lib/embulk/input/marketo_api/soap/base.rb +1 -0
- data/test/embulk/input/marketo/test_activity_log.rb +73 -6
- data/test/embulk/input/marketo/test_base.rb +0 -10
- metadata +16 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 803b16c2edca4432ffcb1f32e9914d944b3747dd
|
4
|
+
data.tar.gz: bb28951330b3b3ac1a8d3bf7a3e81541915268e2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53f1320084a90a824af96b5205ae05f3d8596e79169abc7b15282c67d359ca8c26b8c1e433dcab5ff7b678ba1b239347b7ebd9eda547eb79bbde6ca931227aed
|
7
|
+
data.tar.gz: e6a1e61e3a7d4d0b875b0e704298d7e96d0e1ab395125e461ef704ef069267ac407b515538e2576dbf7ada5420b2f8b473a5d04337f5600648dd5e3649d2c7f6
|
data/CHANGELOG.md
CHANGED
@@ -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
|
[](https://travis-ci.org/treasure-data/embulk-input-marketo)
|
2
|
-
|
3
2
|
[](https://codeclimate.com/github/treasure-data/embulk-input-marketo)
|
4
|
-
|
5
3
|
[](https://codeclimate.com/github/treasure-data/embulk-input-marketo/coverage)
|
4
|
+
[](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
|
-
- **
|
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.
|
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
|
-
|
42
|
+
range = format_range(config)
|
16
43
|
|
17
|
-
schema = client.metadata(
|
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(
|
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 = {
|
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
|
-
|
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
|
-
|
35
|
-
|
36
|
-
|
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
|
-
|
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}"
|
@@ -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(
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
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.
|
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-
|
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:
|