embulk-input-marketo 0.5.7.alpha.4 → 0.5.7.alpha.5
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/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:
|