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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c42c9fcf28e826912b2e3c1f0952ba1d25b4652e
4
- data.tar.gz: 87eb0b019feda052f4dd4c87cc8df852ffc2e33b
3
+ metadata.gz: eee177691c3a0ab66a962ff6a4d3fb6773e55217
4
+ data.tar.gz: 73c4017cbe372d9e5bac35c085750b7edf690030
5
5
  SHA512:
6
- metadata.gz: a305f0e763086fb4cb6763840b3b7bffde0c475e9a0acf2e42a404341dc7dbe7a6bfdcce66727a9bd6febd48f55dd560b23cab9063c90a65dcdb8dd1887523e9
7
- data.tar.gz: 250082fb8a23b96b9860fe7224b0b72ce49def3c791225acdb2a5262292b8d23a5c1958c712c2fe460168b498e34d383505b053a480b4c7b257e78440f7c9e64
6
+ metadata.gz: 103f84a50be5589e023d2d7ed353c20e2509deeece64257fcc31393d3d3e89c33208b3ea5779f2f69126abf0ac18ca1227bb1fb4859955d64a2d49d8041f9f59
7
+ data.tar.gz: f425bda7a48ad4aa94b50a039b7825ac8480ea4e568a2e8cd1ebbddfd0fcede9572226de5f3f17d1a63ab98d8112169b33631b8a751ffcb0aaff6225f165d170
data/build.gradle CHANGED
@@ -16,7 +16,7 @@ repositories {
16
16
  configurations {
17
17
  provided
18
18
  }
19
- version = "0.5.7.alpha.4"
19
+ version = "0.5.7.alpha.5"
20
20
  sourceCompatibility = 1.7
21
21
  targetCompatibility = 1.7
22
22
 
@@ -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().orNull();
41
- return new FileInputStream(marketoService.extractAllActivity(fromDate, MarketoUtils.addDate(fromDate, task.getFetchDays()), task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond()));
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().orNull();
46
- File file = marketoService.extractLead(fromDate, MarketoUtils.addDate(fromDate, task.getFetchDays()), fieldNames, task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond());
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
- @ConfigDefault("null")
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
- if (!task.getFromDate().isPresent()) {
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
- super.validateInputTask(task);
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<String> latestUIds = null;
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
- if (!currentLatestFetchTime.equals(0L)) {
125
- configDiff.set(LATEST_FETCH_TIME, currentLatestFetchTime);
126
- DateFormat df = new SimpleDateFormat(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
127
- configDiff.set("from_date", df.format(new Date(currentLatestFetchTime)));
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
- DateTime currentTimestamp = null;
231
+ long currentTimestamp = 0L;
207
232
  if (task.getLatestFetchTime().isPresent()) {
208
- currentTimestamp = new DateTime(task.getLatestFetchTime().get());
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
- while (csvTokenizer.hasNextColumn()) {
223
- values.add(csvTokenizer.nextColumnOrNull());
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
- DateTime timestamp = ISO_DATETIME_FORMAT.parseDateTime(incrementalTimeStamp);
240
- if (currentTimestamp == null) {
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
- int compareTo = currentTimestamp.compareTo(timestamp);
245
- if (compareTo < 0) {
246
- currentTimestamp = timestamp;
247
- //switch timestamp
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 == null ? 0L : currentTimestamp.getMillis());
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
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-26 00:00:00.000000000 Z
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: