embulk-input-marketo 0.5.7.alpha.4 → 0.5.7.alpha.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/build.gradle +1 -1
- data/src/main/java/org/embulk/input/marketo/MarketoInputPluginDelegate.java +25 -0
- data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +1 -8
- data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +2 -2
- data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +2 -2
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +56 -31
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +5 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +2 -0
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: eee177691c3a0ab66a962ff6a4d3fb6773e55217
|
4
|
+
data.tar.gz: 73c4017cbe372d9e5bac35c085750b7edf690030
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 103f84a50be5589e023d2d7ed353c20e2509deeece64257fcc31393d3d3e89c33208b3ea5779f2f69126abf0ac18ca1227bb1fb4859955d64a2d49d8041f9f59
|
7
|
+
data.tar.gz: f425bda7a48ad4aa94b50a039b7825ac8480ea4e568a2e8cd1ebbddfd0fcede9572226de5f3f17d1a63ab98d8112169b33631b8a751ffcb0aaff6225f165d170
|
data/build.gradle
CHANGED
@@ -2,10 +2,12 @@ package org.embulk.input.marketo;
|
|
2
2
|
|
3
3
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
4
4
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
5
|
+
import com.google.common.base.Optional;
|
5
6
|
import org.embulk.base.restclient.DispatchingRestClientInputPluginDelegate;
|
6
7
|
import org.embulk.base.restclient.RestClientInputPluginDelegate;
|
7
8
|
import org.embulk.config.Config;
|
8
9
|
import org.embulk.config.ConfigDefault;
|
10
|
+
import org.embulk.config.ConfigException;
|
9
11
|
import org.embulk.input.marketo.delegate.ActivityBulkExtractInputPlugin;
|
10
12
|
import org.embulk.input.marketo.delegate.CampaignInputPlugin;
|
11
13
|
import org.embulk.input.marketo.delegate.LeadBulkExtractInputPlugin;
|
@@ -13,6 +15,8 @@ import org.embulk.input.marketo.delegate.LeadWithListInputPlugin;
|
|
13
15
|
import org.embulk.input.marketo.delegate.LeadWithProgramInputPlugin;
|
14
16
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
15
17
|
|
18
|
+
import java.util.Date;
|
19
|
+
|
16
20
|
public class MarketoInputPluginDelegate
|
17
21
|
extends DispatchingRestClientInputPluginDelegate<MarketoInputPluginDelegate.PluginTask>
|
18
22
|
{
|
@@ -37,6 +41,17 @@ public class MarketoInputPluginDelegate
|
|
37
41
|
@Config("maximum_retries_interval_milis")
|
38
42
|
@ConfigDefault("120000")
|
39
43
|
Integer getMaximumRetriesIntervalMilis();
|
44
|
+
|
45
|
+
@Config("hidden_from_date")
|
46
|
+
@ConfigDefault("\"2017-09-01\"")
|
47
|
+
@Override
|
48
|
+
Date getFromDate();
|
49
|
+
|
50
|
+
void setFromDate(Date fromDate);
|
51
|
+
|
52
|
+
@Config("from_date")
|
53
|
+
@ConfigDefault("null")
|
54
|
+
Optional<Date> getWrappedFromDate();
|
40
55
|
}
|
41
56
|
|
42
57
|
@SuppressWarnings("unchecked")
|
@@ -44,6 +59,16 @@ public class MarketoInputPluginDelegate
|
|
44
59
|
protected RestClientInputPluginDelegate dispatchPerTask(PluginTask task)
|
45
60
|
{
|
46
61
|
Target target = task.getTarget();
|
62
|
+
switch (target) {
|
63
|
+
case LEAD:
|
64
|
+
case ACTIVITY:
|
65
|
+
if (!task.getWrappedFromDate().isPresent()) {
|
66
|
+
throw new ConfigException("From date is required for target LEAD or ACTIVITY");
|
67
|
+
}
|
68
|
+
Date date = task.getWrappedFromDate().get();
|
69
|
+
task.setFromDate(date);
|
70
|
+
break;
|
71
|
+
}
|
47
72
|
return target.getRestClientInputPluginDelegate();
|
48
73
|
}
|
49
74
|
|
@@ -12,6 +12,7 @@ import org.embulk.base.restclient.record.ServiceRecord;
|
|
12
12
|
import org.embulk.base.restclient.record.ValueLocator;
|
13
13
|
import org.embulk.input.marketo.model.MarketoField;
|
14
14
|
import org.embulk.spi.Exec;
|
15
|
+
import org.joda.time.DateTime;
|
15
16
|
import org.slf4j.Logger;
|
16
17
|
|
17
18
|
import javax.annotation.Nullable;
|
@@ -90,14 +91,6 @@ public class MarketoUtils
|
|
90
91
|
return kvMap;
|
91
92
|
}
|
92
93
|
|
93
|
-
public static Date addDate(Date fromDate, Integer addDate)
|
94
|
-
{
|
95
|
-
Calendar c = Calendar.getInstance();
|
96
|
-
c.setTime(fromDate);
|
97
|
-
c.add(Calendar.DATE, addDate);
|
98
|
-
return c.getTime();
|
99
|
-
}
|
100
|
-
|
101
94
|
public static String buildColumnName(String prefix, String columnName)
|
102
95
|
{
|
103
96
|
return prefix + "_" + columnName;
|
@@ -37,8 +37,8 @@ public class ActivityBulkExtractInputPlugin extends MarketoBaseBulkExtractInputP
|
|
37
37
|
{
|
38
38
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
39
39
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
40
|
-
Date fromDate = task.getFromDate()
|
41
|
-
return new FileInputStream(marketoService.extractAllActivity(fromDate,
|
40
|
+
Date fromDate = task.getFromDate();
|
41
|
+
return new FileInputStream(marketoService.extractAllActivity(fromDate, task.getToDate().get(), task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond()));
|
42
42
|
}
|
43
43
|
catch (FileNotFoundException e) {
|
44
44
|
LOGGER.error("Exception when trying to extract activity", e);
|
@@ -42,8 +42,8 @@ public class LeadBulkExtractInputPlugin extends MarketoBaseBulkExtractInputPlugi
|
|
42
42
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
43
43
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
44
44
|
List<String> fieldNames = task.getExtractedFields();
|
45
|
-
Date fromDate = task.getFromDate()
|
46
|
-
File file = marketoService.extractLead(fromDate,
|
45
|
+
Date fromDate = task.getFromDate();
|
46
|
+
File file = marketoService.extractLead(fromDate, task.getToDate().get(), fieldNames, task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond());
|
47
47
|
return new FileInputStream(file);
|
48
48
|
}
|
49
49
|
catch (FileNotFoundException e) {
|
@@ -52,11 +52,14 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
52
52
|
|
53
53
|
private static final DateTimeFormatter ISO_DATETIME_FORMAT = ISODateTimeFormat.dateTimeParser();
|
54
54
|
|
55
|
+
private static final String IMPORTED_RECORD_COUNT = "imported";
|
56
|
+
|
57
|
+
private static final String FROM_DATE = "from_date";
|
58
|
+
|
55
59
|
public interface PluginTask extends MarketoBaseInputPluginDelegate.PluginTask, CsvTokenizer.PluginTask
|
56
60
|
{
|
57
61
|
@Config("from_date")
|
58
|
-
|
59
|
-
Optional<Date> getFromDate();
|
62
|
+
Date getFromDate();
|
60
63
|
|
61
64
|
@Config("fetch_days")
|
62
65
|
@ConfigDefault("1")
|
@@ -80,6 +83,12 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
80
83
|
@Config("latest_uids")
|
81
84
|
@ConfigDefault("[]")
|
82
85
|
Set<String> getPreviousUids();
|
86
|
+
|
87
|
+
@Config("to_date")
|
88
|
+
@ConfigDefault("null")
|
89
|
+
Optional<Date> getToDate();
|
90
|
+
|
91
|
+
void setToDate(Date toDate);
|
83
92
|
}
|
84
93
|
|
85
94
|
private String incrementalColumn;
|
@@ -95,13 +104,28 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
95
104
|
@Override
|
96
105
|
public void validateInputTask(T task)
|
97
106
|
{
|
98
|
-
|
107
|
+
super.validateInputTask(task);
|
108
|
+
if (task.getFromDate() == null) {
|
99
109
|
throw new ConfigException("From date is required for Bulk Extract");
|
100
110
|
}
|
101
111
|
if (task.getFetchDays() > 30) {
|
102
112
|
throw new ConfigException("Marketo bulk extract fetch days can't be more than 30");
|
103
113
|
}
|
104
|
-
|
114
|
+
//Calculate to date
|
115
|
+
DateTime toDate = getToDate(task);
|
116
|
+
task.setToDate(toDate.toDate());
|
117
|
+
}
|
118
|
+
|
119
|
+
public DateTime getToDate(T task)
|
120
|
+
{
|
121
|
+
Date fromDate = task.getFromDate();
|
122
|
+
DateTime dateTime = new DateTime(fromDate);
|
123
|
+
DateTime toDate = dateTime.plusDays(task.getFetchDays());
|
124
|
+
if (toDate.isAfter(task.getJobStartTime())) {
|
125
|
+
//Minus 1 hour and lock down toDate
|
126
|
+
toDate = task.getJobStartTime().minusHours(1);
|
127
|
+
}
|
128
|
+
return toDate;
|
105
129
|
}
|
106
130
|
|
107
131
|
@Override
|
@@ -109,8 +133,10 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
109
133
|
{
|
110
134
|
ConfigDiff configDiff = super.buildConfigDiff(task, schema, taskCount, taskReports);
|
111
135
|
Long currentLatestFetchTime = 0L;
|
112
|
-
Set
|
136
|
+
Set latestUIds = null;
|
113
137
|
if (incrementalColumn != null) {
|
138
|
+
int imported = 0;
|
139
|
+
DateFormat df = new SimpleDateFormat(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
|
114
140
|
for (TaskReport taskReport : taskReports) {
|
115
141
|
Long latestFetchTime = taskReport.get(Long.class, LATEST_FETCH_TIME);
|
116
142
|
if (latestFetchTime == null) {
|
@@ -120,13 +146,12 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
120
146
|
currentLatestFetchTime = latestFetchTime;
|
121
147
|
latestUIds = taskReport.get(Set.class, LATEST_UID_LIST);
|
122
148
|
}
|
149
|
+
imported = imported + taskReport.get(Integer.class, IMPORTED_RECORD_COUNT);
|
123
150
|
}
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
configDiff.set(LATEST_UID_LIST, latestUIds);
|
129
|
-
}
|
151
|
+
// in case of we didn't import anything but search range is entirely in the past. Then we should move the the range anyway.
|
152
|
+
configDiff.set(FROM_DATE, df.format(task.getToDate().get()));
|
153
|
+
configDiff.set(LATEST_FETCH_TIME, currentLatestFetchTime);
|
154
|
+
configDiff.set(LATEST_UID_LIST, latestUIds);
|
130
155
|
}
|
131
156
|
return configDiff;
|
132
157
|
}
|
@@ -203,9 +228,9 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
203
228
|
Set<String> latestUids = task.getPreviousUids();
|
204
229
|
TaskReport taskReport = Exec.newTaskReport();
|
205
230
|
int imported = 0;
|
206
|
-
|
231
|
+
long currentTimestamp = 0L;
|
207
232
|
if (task.getLatestFetchTime().isPresent()) {
|
208
|
-
currentTimestamp =
|
233
|
+
currentTimestamp = task.getLatestFetchTime().get();
|
209
234
|
}
|
210
235
|
try (LineDecoder lineDecoder = new LineDecoder(new InputStreamFileInput(task.getBufferAllocator(), inputStream), task)) {
|
211
236
|
CsvTokenizer csvTokenizer = new CsvTokenizer(lineDecoder, task);
|
@@ -219,8 +244,13 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
219
244
|
}
|
220
245
|
while (csvTokenizer.nextRecord() && (imported < PREVIEW_RECORD_LIMIT || !Exec.isPreview())) {
|
221
246
|
List<String> values = new ArrayList<>();
|
222
|
-
|
223
|
-
|
247
|
+
try {
|
248
|
+
while (csvTokenizer.hasNextColumn()) {
|
249
|
+
values.add(csvTokenizer.nextColumnOrNull());
|
250
|
+
}
|
251
|
+
}
|
252
|
+
catch (CsvTokenizer.InvalidValueException ex) {
|
253
|
+
throw new DataException("Encounter exception when parse csv file. Please check the quote or escape character", ex);
|
224
254
|
}
|
225
255
|
final Map<String, String> kvMap = MarketoUtils.zip(headers, values);
|
226
256
|
ObjectNode objectNode = MarketoUtils.OBJECT_MAPPER.valueToTree(kvMap);
|
@@ -236,31 +266,26 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
236
266
|
}
|
237
267
|
}
|
238
268
|
String incrementalTimeStamp = kvMap.get(incrementalColumn);
|
239
|
-
|
240
|
-
if (currentTimestamp
|
269
|
+
long timestamp = ISO_DATETIME_FORMAT.parseDateTime(incrementalTimeStamp).getMillis();
|
270
|
+
if (currentTimestamp < timestamp) {
|
241
271
|
currentTimestamp = timestamp;
|
272
|
+
//switch timestamp
|
273
|
+
latestUids.clear();
|
242
274
|
}
|
243
|
-
else {
|
244
|
-
|
245
|
-
if (
|
246
|
-
|
247
|
-
|
248
|
-
latestUids.clear();
|
249
|
-
}
|
250
|
-
else if (compareTo == 0) {
|
251
|
-
//timestamp is equal
|
252
|
-
if (uidColumn != null) {
|
253
|
-
JsonNode uidField = objectNode.get(uidColumn);
|
254
|
-
latestUids.add(uidField.asText());
|
255
|
-
}
|
275
|
+
else if (currentTimestamp == timestamp) {
|
276
|
+
//timestamp is equal
|
277
|
+
if (uidColumn != null) {
|
278
|
+
JsonNode uidField = objectNode.get(uidColumn);
|
279
|
+
latestUids.add(uidField.asText());
|
256
280
|
}
|
257
281
|
}
|
258
282
|
recordImporter.importRecord(new AllStringJacksonServiceRecord(objectNode), pageBuilder);
|
259
283
|
imported++;
|
260
284
|
}
|
261
285
|
}
|
262
|
-
taskReport.set(LATEST_FETCH_TIME, currentTimestamp
|
286
|
+
taskReport.set(LATEST_FETCH_TIME, currentTimestamp);
|
263
287
|
taskReport.set(LATEST_UID_LIST, latestUids);
|
288
|
+
taskReport.set(IMPORTED_RECORD_COUNT, imported);
|
264
289
|
return taskReport;
|
265
290
|
}
|
266
291
|
|
@@ -14,6 +14,7 @@ import org.embulk.spi.Exec;
|
|
14
14
|
import org.embulk.spi.Schema;
|
15
15
|
import org.embulk.util.retryhelper.jetty92.DefaultJetty92ClientCreator;
|
16
16
|
import org.embulk.util.retryhelper.jetty92.Jetty92RetryHelper;
|
17
|
+
import org.joda.time.DateTime;
|
17
18
|
|
18
19
|
import java.util.List;
|
19
20
|
|
@@ -50,6 +51,9 @@ public abstract class MarketoBaseInputPluginDelegate<T extends MarketoBaseInputP
|
|
50
51
|
|
51
52
|
void setExtractedFields(List<String> extractedFields);
|
52
53
|
|
54
|
+
DateTime getJobStartTime();
|
55
|
+
|
56
|
+
void setJobStartTime(DateTime dateTime);
|
53
57
|
}
|
54
58
|
|
55
59
|
@Override
|
@@ -61,6 +65,7 @@ public abstract class MarketoBaseInputPluginDelegate<T extends MarketoBaseInputP
|
|
61
65
|
@Override
|
62
66
|
public void validateInputTask(T task)
|
63
67
|
{
|
68
|
+
task.setJobStartTime(DateTime.now());
|
64
69
|
}
|
65
70
|
|
66
71
|
@VisibleForTesting
|
@@ -128,6 +128,7 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
128
128
|
if (accessTokenResponse.hasError()) {
|
129
129
|
throw new DataException(accessTokenResponse.getErrorDescription());
|
130
130
|
}
|
131
|
+
LOGGER.info("Acquired new access token");
|
131
132
|
return accessTokenResponse.getAccessToken();
|
132
133
|
}
|
133
134
|
|
@@ -194,6 +195,7 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
194
195
|
String code = error.getCode();
|
195
196
|
switch (code) {
|
196
197
|
case "602":
|
198
|
+
LOGGER.info("Access token expired");
|
197
199
|
renewAccessToken();
|
198
200
|
return true;
|
199
201
|
case "606":
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: embulk-input-marketo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.7.alpha.
|
4
|
+
version: 0.5.7.alpha.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tai Khuu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -92,9 +92,9 @@ files:
|
|
92
92
|
- src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java
|
93
93
|
- classpath/jetty-http-9.2.14.v20151106.jar
|
94
94
|
- classpath/embulk-base-restclient-0.5.3.jar
|
95
|
+
- classpath/embulk-input-marketo-0.5.7.alpha.5.jar
|
95
96
|
- classpath/jetty-client-9.2.14.v20151106.jar
|
96
97
|
- classpath/jetty-util-9.2.14.v20151106.jar
|
97
|
-
- classpath/embulk-input-marketo-0.5.7.alpha.4.jar
|
98
98
|
- classpath/embulk-util-retryhelper-jetty92-0.5.3.jar
|
99
99
|
- classpath/jetty-io-9.2.14.v20151106.jar
|
100
100
|
homepage:
|