embulk-input-marketo 0.5.7.alpha.2 → 0.5.7.alpha.3
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 +5 -5
- data/src/main/java/org/embulk/input/marketo/MarketoService.java +1 -1
- data/src/main/java/org/embulk/input/marketo/MarketoServiceImpl.java +9 -30
- data/src/main/java/org/embulk/input/marketo/MarketoUtils.java +26 -93
- data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +7 -3
- data/src/main/java/org/embulk/input/marketo/delegate/LeadWithListInputPlugin.java +5 -3
- data/src/main/java/org/embulk/input/marketo/delegate/LeadWithProgramInputPlugin.java +5 -3
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseBulkExtractInputPlugin.java +88 -16
- data/src/main/java/org/embulk/input/marketo/delegate/MarketoBaseInputPluginDelegate.java +11 -0
- data/src/main/java/org/embulk/input/marketo/rest/MarketoRestClient.java +3 -3
- 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: d74b33cde7c0649fe4f4cac9de7180e1ae1facce
|
4
|
+
data.tar.gz: 9c55a46eb01f9ff2c7d304529d90a21528ae7a6f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3625b3fe800f9d005811df70a7f881f2183ad0a82dff1d5a5917955119c0594cc0848d73a5ef913175de6fb9f4449fc96fabed9f03ba5fd08ec0e45ad0ead85
|
7
|
+
data.tar.gz: db721e1064761acaf2d95f0bccc877985a2279b9ef5bf8b0a88ff1985dabe35d6cf8fbf146b7b050c9bfcf3421675fff5c937c9b547df9a1a885fc72a33d7f63
|
data/build.gradle
CHANGED
@@ -16,18 +16,18 @@ repositories {
|
|
16
16
|
configurations {
|
17
17
|
provided
|
18
18
|
}
|
19
|
-
version = "0.5.7.alpha.
|
19
|
+
version = "0.5.7.alpha.3"
|
20
20
|
sourceCompatibility = 1.7
|
21
21
|
targetCompatibility = 1.7
|
22
22
|
|
23
23
|
dependencies {
|
24
|
-
compile "org.embulk:embulk-core:0.8
|
25
|
-
provided "org.embulk:embulk-core:0.8
|
24
|
+
compile "org.embulk:embulk-core:0.8.+"
|
25
|
+
provided "org.embulk:embulk-core:0.8.+"
|
26
26
|
compile "org.embulk.base.restclient:embulk-base-restclient:0.5.3"
|
27
27
|
compile "org.embulk.base.restclient:embulk-util-retryhelper-jetty92:0.5.3"
|
28
28
|
testCompile "junit:junit:4.+"
|
29
|
-
testCompile "org.embulk:embulk-core:0.8
|
30
|
-
testCompile "org.embulk:embulk-test:0.8
|
29
|
+
testCompile "org.embulk:embulk-core:0.8.+:tests"
|
30
|
+
testCompile "org.embulk:embulk-test:0.8.+"
|
31
31
|
testCompile "org.mockito:mockito-core:2.+"
|
32
32
|
}
|
33
33
|
|
@@ -18,7 +18,7 @@ public interface MarketoService
|
|
18
18
|
|
19
19
|
List<MarketoField> describeLeadByLists();
|
20
20
|
|
21
|
-
File extractLead(Date startTime, Date endTime, List<String>
|
21
|
+
File extractLead(Date startTime, Date endTime, List<String> extractedFields, int pollingTimeIntervalSecond, int bulkJobTimeoutSecond);
|
22
22
|
|
23
23
|
File extractAllActivity(Date startTime, Date endTime, int pollingTimeIntervalSecond, int bulkJobTimeoutSecond);
|
24
24
|
|
@@ -2,18 +2,13 @@ package org.embulk.input.marketo;
|
|
2
2
|
|
3
3
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
4
4
|
import com.google.common.base.Function;
|
5
|
-
import com.google.common.base.Predicate;
|
6
|
-
import com.google.common.collect.FluentIterable;
|
7
|
-
import com.google.common.collect.ImmutableList;
|
8
5
|
import com.google.common.collect.Iterables;
|
9
6
|
import com.google.common.io.ByteStreams;
|
10
7
|
import org.embulk.input.marketo.model.MarketoField;
|
11
8
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
12
9
|
import org.embulk.input.marketo.rest.RecordPagingIterable;
|
13
|
-
import org.embulk.spi.Column;
|
14
10
|
import org.embulk.spi.DataException;
|
15
11
|
import org.embulk.spi.Exec;
|
16
|
-
import org.embulk.spi.type.Types;
|
17
12
|
import org.slf4j.Logger;
|
18
13
|
|
19
14
|
import javax.annotation.Nullable;
|
@@ -36,10 +31,6 @@ public class MarketoServiceImpl implements MarketoService
|
|
36
31
|
|
37
32
|
private static final String DEFAULT_FILE_FORMAT = "csv";
|
38
33
|
|
39
|
-
private static final String LIST_ID_COLUMN_NAME = "listId";
|
40
|
-
|
41
|
-
private static final String PROGRAM_ID_COLUMN_NAME = "programId";
|
42
|
-
|
43
34
|
private MarketoRestClient marketoRestClient;
|
44
35
|
|
45
36
|
public MarketoServiceImpl(MarketoRestClient marketoRestClient)
|
@@ -48,9 +39,9 @@ public class MarketoServiceImpl implements MarketoService
|
|
48
39
|
}
|
49
40
|
|
50
41
|
@Override
|
51
|
-
public File extractLead(Date startTime, Date endTime, List<String>
|
42
|
+
public File extractLead(Date startTime, Date endTime, List<String> extractedFields, int pollingTimeIntervalSecond, int bulkJobTimeoutSecond)
|
52
43
|
{
|
53
|
-
String exportID = marketoRestClient.createLeadBulkExtract(startTime, endTime,
|
44
|
+
String exportID = marketoRestClient.createLeadBulkExtract(startTime, endTime, extractedFields);
|
54
45
|
marketoRestClient.startLeadBulkExtract(exportID);
|
55
46
|
try {
|
56
47
|
marketoRestClient.waitLeadExportJobComplete(exportID, pollingTimeIntervalSecond, bulkJobTimeoutSecond);
|
@@ -66,7 +57,7 @@ public class MarketoServiceImpl implements MarketoService
|
|
66
57
|
private File saveExtractedFile(String exportID, InputStream leadBulkExtractResult)
|
67
58
|
{
|
68
59
|
File tempFile = Exec.getTempFileSpace().createTempFile(DEFAULT_FILE_FORMAT);
|
69
|
-
try (OutputStream fileOuputStream = new FileOutputStream(tempFile)){
|
60
|
+
try (OutputStream fileOuputStream = new FileOutputStream(tempFile)) {
|
70
61
|
ByteStreams.copy(leadBulkExtractResult, fileOuputStream);
|
71
62
|
}
|
72
63
|
catch (IOException e) {
|
@@ -99,13 +90,13 @@ public class MarketoServiceImpl implements MarketoService
|
|
99
90
|
List<Iterable<ObjectNode>> iterables = new ArrayList<>();
|
100
91
|
for (ObjectNode node : lists) {
|
101
92
|
final String id = node.get("id").asText();
|
102
|
-
iterables.add(Iterables.transform(marketoRestClient.getLeadsByList(id,
|
93
|
+
iterables.add(Iterables.transform(marketoRestClient.getLeadsByList(id, fieldNames), new Function<ObjectNode, ObjectNode>()
|
103
94
|
{
|
104
95
|
@Nullable
|
105
96
|
@Override
|
106
97
|
public ObjectNode apply(@Nullable ObjectNode input)
|
107
98
|
{
|
108
|
-
input.put(LIST_ID_COLUMN_NAME, id);
|
99
|
+
input.put(MarketoUtils.LIST_ID_COLUMN_NAME, id);
|
109
100
|
return input;
|
110
101
|
}
|
111
102
|
}));
|
@@ -113,18 +104,6 @@ public class MarketoServiceImpl implements MarketoService
|
|
113
104
|
return Iterables.concat(iterables);
|
114
105
|
}
|
115
106
|
|
116
|
-
public static ImmutableList<String> filterFieldName(List<String> fieldNames, final String columName)
|
117
|
-
{
|
118
|
-
return FluentIterable.from(fieldNames).filter(new Predicate<String>()
|
119
|
-
{
|
120
|
-
@Override
|
121
|
-
public boolean apply(@Nullable String input)
|
122
|
-
{
|
123
|
-
return !columName.equals(input);
|
124
|
-
}
|
125
|
-
}).toList();
|
126
|
-
}
|
127
|
-
|
128
107
|
@Override
|
129
108
|
public Iterable<ObjectNode> getAllProgramLead(List<String> fieldNames)
|
130
109
|
{
|
@@ -132,13 +111,13 @@ public class MarketoServiceImpl implements MarketoService
|
|
132
111
|
List<Iterable<ObjectNode>> iterables = new ArrayList<>();
|
133
112
|
for (ObjectNode node : lists) {
|
134
113
|
final String id = node.get("id").asText();
|
135
|
-
iterables.add(Iterables.transform(marketoRestClient.getLeadsByProgram(id,
|
114
|
+
iterables.add(Iterables.transform(marketoRestClient.getLeadsByProgram(id, fieldNames), new Function<ObjectNode, ObjectNode>()
|
136
115
|
{
|
137
116
|
@Nullable
|
138
117
|
@Override
|
139
118
|
public ObjectNode apply(@Nullable ObjectNode input)
|
140
119
|
{
|
141
|
-
input.put(PROGRAM_ID_COLUMN_NAME, id);
|
120
|
+
input.put(MarketoUtils.PROGRAM_ID_COLUMN_NAME, id);
|
142
121
|
return input;
|
143
122
|
}
|
144
123
|
}));
|
@@ -162,7 +141,7 @@ public class MarketoServiceImpl implements MarketoService
|
|
162
141
|
public List<MarketoField> describeLeadByProgram()
|
163
142
|
{
|
164
143
|
List<MarketoField> columns = marketoRestClient.describeLead();
|
165
|
-
columns.add(new MarketoField(PROGRAM_ID_COLUMN_NAME, MarketoField.MarketoDataType.STRING));
|
144
|
+
columns.add(new MarketoField(MarketoUtils.PROGRAM_ID_COLUMN_NAME, MarketoField.MarketoDataType.STRING));
|
166
145
|
return columns;
|
167
146
|
}
|
168
147
|
|
@@ -170,7 +149,7 @@ public class MarketoServiceImpl implements MarketoService
|
|
170
149
|
public List<MarketoField> describeLeadByLists()
|
171
150
|
{
|
172
151
|
List<MarketoField> columns = marketoRestClient.describeLead();
|
173
|
-
columns.add(new MarketoField(LIST_ID_COLUMN_NAME, MarketoField.MarketoDataType.STRING));
|
152
|
+
columns.add(new MarketoField(MarketoUtils.LIST_ID_COLUMN_NAME, MarketoField.MarketoDataType.STRING));
|
174
153
|
return columns;
|
175
154
|
}
|
176
155
|
}
|
@@ -3,8 +3,7 @@ package org.embulk.input.marketo;
|
|
3
3
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
4
4
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
5
5
|
import com.google.common.base.Function;
|
6
|
-
import com.google.common.
|
7
|
-
import com.google.common.collect.FluentIterable;
|
6
|
+
import com.google.common.collect.Sets;
|
8
7
|
import org.embulk.base.restclient.ServiceResponseMapper;
|
9
8
|
import org.embulk.base.restclient.jackson.JacksonServiceRecord;
|
10
9
|
import org.embulk.base.restclient.jackson.JacksonServiceResponseMapper;
|
@@ -12,31 +11,27 @@ import org.embulk.base.restclient.jackson.JacksonTopLevelValueLocator;
|
|
12
11
|
import org.embulk.base.restclient.record.ServiceRecord;
|
13
12
|
import org.embulk.base.restclient.record.ValueLocator;
|
14
13
|
import org.embulk.input.marketo.model.MarketoField;
|
15
|
-
import org.embulk.spi.Column;
|
16
|
-
import org.embulk.spi.ColumnVisitor;
|
17
|
-
import org.embulk.spi.DataException;
|
18
14
|
import org.embulk.spi.Exec;
|
19
|
-
import org.embulk.spi.Schema;
|
20
15
|
import org.slf4j.Logger;
|
21
16
|
|
22
17
|
import javax.annotation.Nullable;
|
23
18
|
|
24
|
-
import java.
|
19
|
+
import java.util.ArrayList;
|
25
20
|
import java.util.Calendar;
|
26
21
|
import java.util.Date;
|
27
22
|
import java.util.HashMap;
|
28
23
|
import java.util.List;
|
29
24
|
import java.util.Map;
|
25
|
+
import java.util.Set;
|
30
26
|
|
31
27
|
/**
|
32
28
|
* Created by tai.khuu on 9/18/17.
|
33
29
|
*/
|
34
30
|
public class MarketoUtils
|
35
31
|
{
|
36
|
-
private static final Logger LOGGER = Exec.getLogger(MarketoUtils.class);
|
37
32
|
public static final String MARKETO_DATE_TIME_FORMAT = "%Y-%m-%dT%H:%M:%S%z";
|
38
33
|
public static final String MARKETO_DATE_FORMAT = "%Y-%m-%d";
|
39
|
-
|
34
|
+
public static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
40
35
|
public static final Function<ObjectNode, ServiceRecord> TRANSFORM_OBJECT_TO_JACKSON_SERVICE_RECORD_FUNCTION = new Function<ObjectNode, ServiceRecord>()
|
41
36
|
{
|
42
37
|
@Nullable
|
@@ -49,108 +44,41 @@ public class MarketoUtils
|
|
49
44
|
|
50
45
|
public static final String MARKETO_DATE_SIMPLE_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ssZ";
|
51
46
|
|
47
|
+
public static final String LIST_ID_COLUMN_NAME = "listId";
|
48
|
+
|
49
|
+
public static final String PROGRAM_ID_COLUMN_NAME = "programId";
|
50
|
+
|
52
51
|
private MarketoUtils()
|
53
52
|
{
|
54
53
|
}
|
55
54
|
|
56
|
-
public static ServiceResponseMapper<? extends ValueLocator> buildDynamicResponseMapper(List<MarketoField> columns)
|
55
|
+
public static ServiceResponseMapper<? extends ValueLocator> buildDynamicResponseMapper(String prefix, List<MarketoField> columns)
|
57
56
|
{
|
58
57
|
JacksonServiceResponseMapper.Builder builder = JacksonServiceResponseMapper.builder();
|
59
58
|
for (MarketoField column : columns) {
|
59
|
+
String columName = buildColumnName(prefix, column.getName());
|
60
60
|
MarketoField.MarketoDataType marketoDataType = column.getMarketoDataType();
|
61
61
|
if (marketoDataType.getFormat().isPresent()) {
|
62
|
-
builder.add(new JacksonTopLevelValueLocator(column.getName()),
|
62
|
+
builder.add(new JacksonTopLevelValueLocator(column.getName()), columName, marketoDataType.getType(), marketoDataType.getFormat().get());
|
63
63
|
}
|
64
64
|
else {
|
65
|
-
builder.add(new JacksonTopLevelValueLocator(column.getName()),
|
65
|
+
builder.add(new JacksonTopLevelValueLocator(column.getName()), columName, marketoDataType.getType());
|
66
66
|
}
|
67
67
|
}
|
68
68
|
return builder.build();
|
69
69
|
}
|
70
70
|
|
71
|
-
public static List<String>
|
72
|
-
{
|
73
|
-
return FluentIterable.from(schema.getColumns()).transform(new Function<Column, String>()
|
74
|
-
{
|
75
|
-
@Override
|
76
|
-
public String apply(Column input)
|
77
|
-
{
|
78
|
-
return input.getName();
|
79
|
-
}
|
80
|
-
}).toList();
|
81
|
-
}
|
82
|
-
public static ObjectNode transformToObjectNode(final Map<String, String> kvMap, Schema schema)
|
71
|
+
public static List<String> getFieldNameFromMarketoFields(List<MarketoField> columns, String... excludedFields)
|
83
72
|
{
|
84
|
-
|
85
|
-
|
86
|
-
{
|
87
|
-
|
88
|
-
|
89
|
-
{
|
90
|
-
String s = kvMap.get(column.getName());
|
91
|
-
objectNode.put(column.getName(), s == null ? null : Boolean.parseBoolean(s));
|
92
|
-
}
|
93
|
-
|
94
|
-
@Override
|
95
|
-
public void longColumn(Column column)
|
96
|
-
{
|
97
|
-
String s = kvMap.get(column.getName());
|
98
|
-
long l = 0;
|
99
|
-
try {
|
100
|
-
l = Long.parseLong(s);
|
101
|
-
}
|
102
|
-
catch (NumberFormatException ex) {
|
103
|
-
if (!Strings.isNullOrEmpty(s)) {
|
104
|
-
LOGGER.error("Can't convert value : [{}] to long", s, ex);
|
105
|
-
throw new DataException("Can't parse value to long");
|
106
|
-
}
|
107
|
-
}
|
108
|
-
objectNode.put(column.getName(), l);
|
109
|
-
}
|
110
|
-
|
111
|
-
@Override
|
112
|
-
public void doubleColumn(Column column)
|
113
|
-
{
|
114
|
-
String s = kvMap.get(column.getName());
|
115
|
-
try {
|
116
|
-
objectNode.put(column.getName(), s == null ? null : Double.parseDouble(s));
|
117
|
-
}
|
118
|
-
catch (NumberFormatException ex) {
|
119
|
-
if (!Strings.isNullOrEmpty(s)) {
|
120
|
-
LOGGER.error("Can't convert value : [{}] to double", s, ex);
|
121
|
-
throw new DataException("Can't parse value to double");
|
122
|
-
}
|
123
|
-
}
|
124
|
-
}
|
125
|
-
|
126
|
-
@Override
|
127
|
-
public void stringColumn(Column column)
|
128
|
-
{
|
129
|
-
String s = kvMap.get(column.getName());
|
130
|
-
objectNode.put(column.getName(), s);
|
131
|
-
}
|
132
|
-
|
133
|
-
@Override
|
134
|
-
public void timestampColumn(Column column)
|
135
|
-
{
|
136
|
-
String s = kvMap.get(column.getName());
|
137
|
-
objectNode.put(column.getName(), s);
|
138
|
-
}
|
139
|
-
|
140
|
-
@Override
|
141
|
-
public void jsonColumn(Column column)
|
142
|
-
{
|
143
|
-
String s = kvMap.get(column.getName());
|
144
|
-
try {
|
145
|
-
objectNode.set(column.getName(), s != null ? OBJECT_MAPPER.readTree(s) : null);
|
146
|
-
}
|
147
|
-
catch (IOException e) {
|
148
|
-
LOGGER.error("Can't convert column [{}] value [{}] to json", column.getName(), s, e);
|
149
|
-
throw new DataException("Can't convert column " + column.getName() + " value to json");
|
150
|
-
}
|
73
|
+
Set<String> excludeFields= Sets.newHashSet(excludedFields);
|
74
|
+
List<String> extractedFields = new ArrayList<>();
|
75
|
+
for (MarketoField column : columns) {
|
76
|
+
if (excludeFields.contains(column.getName())) {
|
77
|
+
continue;
|
151
78
|
}
|
152
|
-
|
153
|
-
|
79
|
+
extractedFields.add(column.getName());
|
80
|
+
}
|
81
|
+
return extractedFields;
|
154
82
|
}
|
155
83
|
|
156
84
|
public static <K, V> Map<K, V> zip(List<K> keys, List<V> values)
|
@@ -169,4 +97,9 @@ public class MarketoUtils
|
|
169
97
|
c.add(Calendar.DATE, addDate);
|
170
98
|
return c.getTime();
|
171
99
|
}
|
100
|
+
|
101
|
+
public static String buildColumnName(String prefix, String columnName)
|
102
|
+
{
|
103
|
+
return prefix + "_" + columnName;
|
104
|
+
}
|
172
105
|
}
|
@@ -1,10 +1,12 @@
|
|
1
1
|
package org.embulk.input.marketo.delegate;
|
2
2
|
|
3
|
+
import com.fasterxml.jackson.databind.node.ObjectNode;
|
3
4
|
import org.embulk.base.restclient.ServiceResponseMapper;
|
4
5
|
import org.embulk.base.restclient.record.ValueLocator;
|
5
6
|
import org.embulk.input.marketo.MarketoService;
|
6
7
|
import org.embulk.input.marketo.MarketoServiceImpl;
|
7
8
|
import org.embulk.input.marketo.MarketoUtils;
|
9
|
+
import org.embulk.input.marketo.model.MarketoField;
|
8
10
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
9
11
|
import org.embulk.spi.DataException;
|
10
12
|
import org.embulk.spi.Exec;
|
@@ -39,10 +41,10 @@ public class LeadBulkExtractInputPlugin extends MarketoBaseBulkExtractInputPlugi
|
|
39
41
|
{
|
40
42
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
41
43
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
42
|
-
List<String> fieldNames =
|
44
|
+
List<String> fieldNames = task.getExtractedFields();
|
43
45
|
Date fromDate = task.getFromDate().orNull();
|
44
46
|
File file = marketoService.extractLead(fromDate, MarketoUtils.addDate(fromDate, task.getFetchDays()), fieldNames, task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond());
|
45
|
-
|
47
|
+
return new FileInputStream(file);
|
46
48
|
}
|
47
49
|
catch (FileNotFoundException e) {
|
48
50
|
LOGGER.error("File not found", e);
|
@@ -55,7 +57,9 @@ public class LeadBulkExtractInputPlugin extends MarketoBaseBulkExtractInputPlugi
|
|
55
57
|
{
|
56
58
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
57
59
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
58
|
-
|
60
|
+
List<MarketoField> columns = marketoService.describeLead();
|
61
|
+
task.setExtractedFields(MarketoUtils.getFieldNameFromMarketoFields(columns));
|
62
|
+
return MarketoUtils.buildDynamicResponseMapper(task.getSchemaColumnPrefix(), columns);
|
59
63
|
}
|
60
64
|
}
|
61
65
|
}
|
@@ -9,6 +9,7 @@ import org.embulk.config.TaskReport;
|
|
9
9
|
import org.embulk.input.marketo.MarketoService;
|
10
10
|
import org.embulk.input.marketo.MarketoServiceImpl;
|
11
11
|
import org.embulk.input.marketo.MarketoUtils;
|
12
|
+
import org.embulk.input.marketo.model.MarketoField;
|
12
13
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
13
14
|
import org.embulk.spi.Exec;
|
14
15
|
import org.embulk.spi.PageBuilder;
|
@@ -33,8 +34,7 @@ public class LeadWithListInputPlugin extends MarketoBaseInputPluginDelegate<Lead
|
|
33
34
|
{
|
34
35
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
35
36
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
36
|
-
|
37
|
-
FluentIterable<ServiceRecord> serviceRecords = FluentIterable.from(marketoService.getAllListLead(fieldNames)).transform(MarketoUtils.TRANSFORM_OBJECT_TO_JACKSON_SERVICE_RECORD_FUNCTION);
|
37
|
+
FluentIterable<ServiceRecord> serviceRecords = FluentIterable.from(marketoService.getAllListLead(task.getExtractedFields())).transform(MarketoUtils.TRANSFORM_OBJECT_TO_JACKSON_SERVICE_RECORD_FUNCTION);
|
38
38
|
int imported = 0;
|
39
39
|
for (ServiceRecord serviceRecord : serviceRecords) {
|
40
40
|
if (imported >= PREVIEW_RECORD_LIMIT && Exec.isPreview()) {
|
@@ -52,7 +52,9 @@ public class LeadWithListInputPlugin extends MarketoBaseInputPluginDelegate<Lead
|
|
52
52
|
{
|
53
53
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
54
54
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
55
|
-
|
55
|
+
List<MarketoField> columns = marketoService.describeLeadByLists();
|
56
|
+
task.setExtractedFields(MarketoUtils.getFieldNameFromMarketoFields(columns, MarketoUtils.LIST_ID_COLUMN_NAME));
|
57
|
+
return MarketoUtils.buildDynamicResponseMapper(task.getSchemaColumnPrefix(), columns);
|
56
58
|
}
|
57
59
|
}
|
58
60
|
}
|
@@ -9,6 +9,7 @@ import org.embulk.config.TaskReport;
|
|
9
9
|
import org.embulk.input.marketo.MarketoService;
|
10
10
|
import org.embulk.input.marketo.MarketoServiceImpl;
|
11
11
|
import org.embulk.input.marketo.MarketoUtils;
|
12
|
+
import org.embulk.input.marketo.model.MarketoField;
|
12
13
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
13
14
|
import org.embulk.spi.Exec;
|
14
15
|
import org.embulk.spi.PageBuilder;
|
@@ -29,8 +30,7 @@ public class LeadWithProgramInputPlugin extends MarketoBaseInputPluginDelegate<L
|
|
29
30
|
{
|
30
31
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
31
32
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
32
|
-
List<String> fieldNames =
|
33
|
-
|
33
|
+
List<String> fieldNames = task.getExtractedFields();
|
34
34
|
FluentIterable<ServiceRecord> serviceRecords = FluentIterable.from(marketoService.getAllProgramLead(fieldNames)).
|
35
35
|
transform(MarketoUtils.TRANSFORM_OBJECT_TO_JACKSON_SERVICE_RECORD_FUNCTION);
|
36
36
|
int imported = 0;
|
@@ -50,7 +50,9 @@ public class LeadWithProgramInputPlugin extends MarketoBaseInputPluginDelegate<L
|
|
50
50
|
{
|
51
51
|
try (MarketoRestClient marketoRestClient = createMarketoRestClient(task)) {
|
52
52
|
MarketoService marketoService = new MarketoServiceImpl(marketoRestClient);
|
53
|
-
|
53
|
+
List<MarketoField> columns = marketoService.describeLeadByProgram();
|
54
|
+
task.setExtractedFields(MarketoUtils.getFieldNameFromMarketoFields(columns, MarketoUtils.PROGRAM_ID_COLUMN_NAME));
|
55
|
+
return MarketoUtils.buildDynamicResponseMapper(task.getSchemaColumnPrefix(), columns);
|
54
56
|
}
|
55
57
|
}
|
56
58
|
}
|
@@ -4,7 +4,9 @@ import com.fasterxml.jackson.databind.JsonNode;
|
|
4
4
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
5
5
|
import com.google.common.base.Optional;
|
6
6
|
import org.embulk.base.restclient.jackson.JacksonServiceRecord;
|
7
|
+
import org.embulk.base.restclient.jackson.JacksonServiceValue;
|
7
8
|
import org.embulk.base.restclient.record.RecordImporter;
|
9
|
+
import org.embulk.base.restclient.record.ValueLocator;
|
8
10
|
import org.embulk.config.Config;
|
9
11
|
import org.embulk.config.ConfigDefault;
|
10
12
|
import org.embulk.config.ConfigDiff;
|
@@ -25,8 +27,10 @@ import org.embulk.spi.time.Timestamp;
|
|
25
27
|
import org.embulk.spi.time.TimestampParser;
|
26
28
|
import org.embulk.spi.util.InputStreamFileInput;
|
27
29
|
import org.embulk.spi.util.LineDecoder;
|
28
|
-
import org.joda.time.
|
29
|
-
import org.
|
30
|
+
import org.joda.time.DateTime;
|
31
|
+
import org.joda.time.format.DateTimeFormatter;
|
32
|
+
import org.joda.time.format.ISODateTimeFormat;
|
33
|
+
import org.msgpack.value.Value;
|
30
34
|
|
31
35
|
import java.io.InputStream;
|
32
36
|
import java.text.DateFormat;
|
@@ -42,12 +46,12 @@ import java.util.Set;
|
|
42
46
|
*/
|
43
47
|
public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBulkExtractInputPlugin.PluginTask> extends MarketoBaseInputPluginDelegate<T>
|
44
48
|
{
|
45
|
-
private static final Logger LOGGER = Exec.getLogger(MarketoBaseBulkExtractInputPlugin.class);
|
46
|
-
|
47
49
|
private static final String LATEST_FETCH_TIME = "latest_fetch_time";
|
48
50
|
|
49
51
|
private static final String LATEST_UID_LIST = "latest_uids";
|
50
52
|
|
53
|
+
private static final DateTimeFormatter ISO_DATETIME_FORMAT = ISODateTimeFormat.dateTimeParser();
|
54
|
+
|
51
55
|
public interface PluginTask extends MarketoBaseInputPluginDelegate.PluginTask, CsvTokenizer.PluginTask
|
52
56
|
{
|
53
57
|
@Config("from_date")
|
@@ -197,11 +201,10 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
197
201
|
Set<String> latestUids = task.getPreviousUids();
|
198
202
|
TaskReport taskReport = Exec.newTaskReport();
|
199
203
|
int imported = 0;
|
200
|
-
|
204
|
+
DateTime currentTimestamp = null;
|
201
205
|
if (task.getLatestFetchTime().isPresent()) {
|
202
|
-
currentTimestamp =
|
206
|
+
currentTimestamp = new DateTime(task.getLatestFetchTime().get());
|
203
207
|
}
|
204
|
-
TimestampParser timestampParser = new TimestampParser(MarketoUtils.MARKETO_DATE_TIME_FORMAT, DateTimeZone.UTC);
|
205
208
|
try (LineDecoder lineDecoder = new LineDecoder(new InputStreamFileInput(task.getBufferAllocator(), inputStream), task)) {
|
206
209
|
CsvTokenizer csvTokenizer = new CsvTokenizer(lineDecoder, task);
|
207
210
|
if (!csvTokenizer.nextFile()) {
|
@@ -218,21 +221,20 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
218
221
|
values.add(csvTokenizer.nextColumnOrNull());
|
219
222
|
}
|
220
223
|
final Map<String, String> kvMap = MarketoUtils.zip(headers, values);
|
221
|
-
ObjectNode objectNode = MarketoUtils.
|
222
|
-
|
224
|
+
ObjectNode objectNode = MarketoUtils.OBJECT_MAPPER.valueToTree(kvMap);
|
225
|
+
|
226
|
+
if (!kvMap.containsKey(incrementalColumn)) {
|
223
227
|
throw new DataException("Extracted record doesn't have incremental column " + incrementalColumn);
|
224
228
|
}
|
225
|
-
JsonNode incrementalJsonNode = objectNode.get(incrementalColumn);
|
226
229
|
if (uidColumn != null) {
|
227
|
-
|
228
|
-
String uid = uidField.asText();
|
230
|
+
String uid = kvMap.get(uidColumn);
|
229
231
|
if (latestUids.contains(uid)) {
|
230
232
|
//Duplicate value
|
231
233
|
continue;
|
232
234
|
}
|
233
235
|
}
|
234
|
-
String incrementalTimeStamp =
|
235
|
-
|
236
|
+
String incrementalTimeStamp = kvMap.get(incrementalColumn);
|
237
|
+
DateTime timestamp = ISO_DATETIME_FORMAT.parseDateTime(incrementalTimeStamp);
|
236
238
|
if (currentTimestamp == null) {
|
237
239
|
currentTimestamp = timestamp;
|
238
240
|
}
|
@@ -251,13 +253,83 @@ public abstract class MarketoBaseBulkExtractInputPlugin<T extends MarketoBaseBul
|
|
251
253
|
}
|
252
254
|
}
|
253
255
|
}
|
254
|
-
recordImporter.importRecord(new
|
256
|
+
recordImporter.importRecord(new AllStringJacksonServiceRecord(objectNode), pageBuilder);
|
255
257
|
imported++;
|
256
258
|
}
|
257
259
|
}
|
258
|
-
taskReport.set(LATEST_FETCH_TIME, currentTimestamp == null ? null : currentTimestamp.
|
260
|
+
taskReport.set(LATEST_FETCH_TIME, currentTimestamp == null ? null : currentTimestamp.getMillis());
|
259
261
|
taskReport.set(LATEST_UID_LIST, latestUids);
|
260
262
|
return taskReport;
|
261
263
|
}
|
264
|
+
|
262
265
|
protected abstract InputStream getExtractedStream(T task, Schema schema);
|
266
|
+
|
267
|
+
private static class AllStringJacksonServiceRecord extends JacksonServiceRecord
|
268
|
+
{
|
269
|
+
public AllStringJacksonServiceRecord(ObjectNode record)
|
270
|
+
{
|
271
|
+
super(record);
|
272
|
+
}
|
273
|
+
|
274
|
+
@Override
|
275
|
+
public JacksonServiceValue getValue(ValueLocator locator)
|
276
|
+
{
|
277
|
+
// We know that this thing only contain text.
|
278
|
+
JacksonServiceValue value = super.getValue(locator);
|
279
|
+
return new StringConverterJacksonServiceRecord(value.stringValue());
|
280
|
+
}
|
281
|
+
}
|
282
|
+
|
283
|
+
private static class StringConverterJacksonServiceRecord extends JacksonServiceValue
|
284
|
+
{
|
285
|
+
private String textValue;
|
286
|
+
|
287
|
+
public StringConverterJacksonServiceRecord(String textValue)
|
288
|
+
{
|
289
|
+
super(null);
|
290
|
+
this.textValue = textValue;
|
291
|
+
}
|
292
|
+
|
293
|
+
@Override
|
294
|
+
public boolean isNull()
|
295
|
+
{
|
296
|
+
return textValue == null || textValue.equals("null");
|
297
|
+
}
|
298
|
+
|
299
|
+
@Override
|
300
|
+
public boolean booleanValue()
|
301
|
+
{
|
302
|
+
return Boolean.parseBoolean(textValue);
|
303
|
+
}
|
304
|
+
|
305
|
+
@Override
|
306
|
+
public double doubleValue()
|
307
|
+
{
|
308
|
+
return Double.parseDouble(textValue);
|
309
|
+
}
|
310
|
+
|
311
|
+
@Override
|
312
|
+
public Value jsonValue(JsonParser jsonParser)
|
313
|
+
{
|
314
|
+
return jsonParser.parse(textValue);
|
315
|
+
}
|
316
|
+
|
317
|
+
@Override
|
318
|
+
public long longValue()
|
319
|
+
{
|
320
|
+
return Long.parseLong(textValue);
|
321
|
+
}
|
322
|
+
|
323
|
+
@Override
|
324
|
+
public String stringValue()
|
325
|
+
{
|
326
|
+
return textValue;
|
327
|
+
}
|
328
|
+
|
329
|
+
@Override
|
330
|
+
public Timestamp timestampValue(TimestampParser timestampParser)
|
331
|
+
{
|
332
|
+
return timestampParser.parse(textValue);
|
333
|
+
}
|
334
|
+
}
|
263
335
|
}
|
@@ -39,6 +39,17 @@ public abstract class MarketoBaseInputPluginDelegate<T extends MarketoBaseInputP
|
|
39
39
|
@Config("maximum_retries_interval_milis")
|
40
40
|
@ConfigDefault("120000")
|
41
41
|
Integer getMaximumRetriesIntervalMilis();
|
42
|
+
|
43
|
+
@Config("schema_column_prefix")
|
44
|
+
@ConfigDefault("\"mk\"")
|
45
|
+
String getSchemaColumnPrefix();
|
46
|
+
|
47
|
+
@Config("extracted_fields")
|
48
|
+
@ConfigDefault("[]")
|
49
|
+
List<String> getExtractedFields();
|
50
|
+
|
51
|
+
void setExtractedFields(List<String> extractedFields);
|
52
|
+
|
42
53
|
}
|
43
54
|
|
44
55
|
@Override
|
@@ -68,7 +68,6 @@ public class MarketoRestClient extends MarketoBaseRestClient
|
|
68
68
|
|
69
69
|
public interface PluginTask extends Task
|
70
70
|
{
|
71
|
-
|
72
71
|
@Config("account_id")
|
73
72
|
String getAccountId();
|
74
73
|
|
@@ -85,7 +84,6 @@ public class MarketoRestClient extends MarketoBaseRestClient
|
|
85
84
|
@Config("batch_size")
|
86
85
|
@ConfigDefault("300")
|
87
86
|
Integer getBatchSize();
|
88
|
-
|
89
87
|
void setBatchSize(Integer batchSize);
|
90
88
|
}
|
91
89
|
|
@@ -225,6 +223,7 @@ public class MarketoRestClient extends MarketoBaseRestClient
|
|
225
223
|
private void waitExportJobComplete(MarketoRESTEndpoint marketoRESTEndpoint, String exportId, int pollingInterval, int waitTimeout) throws InterruptedException
|
226
224
|
{
|
227
225
|
long waitTime = 0;
|
226
|
+
long waitTimeoutMs = waitTimeout * 1000;
|
228
227
|
long now = System.currentTimeMillis();
|
229
228
|
while (true) {
|
230
229
|
MarketoResponse<ObjectNode> marketoResponse = doGet(this.endPoint + marketoRESTEndpoint.getEndpoint(
|
@@ -238,6 +237,7 @@ public class MarketoRestClient extends MarketoBaseRestClient
|
|
238
237
|
LOGGER.info("Jobs [{}] status is [{}]", exportId, status);
|
239
238
|
switch (status) {
|
240
239
|
case "Completed":
|
240
|
+
LOGGER.info("Total wait time ms is [{}]", waitTime);
|
241
241
|
return;
|
242
242
|
case "Failed":
|
243
243
|
throw new DataException("Bulk extract job failed exportId: " + exportId + " errorMessage: " + objectNode.get("errorMsg").asText());
|
@@ -247,7 +247,7 @@ public class MarketoRestClient extends MarketoBaseRestClient
|
|
247
247
|
}
|
248
248
|
Thread.sleep(pollingInterval * 1000);
|
249
249
|
waitTime = waitTime + (System.currentTimeMillis() - now);
|
250
|
-
if (waitTime >=
|
250
|
+
if (waitTime >= waitTimeoutMs) {
|
251
251
|
throw new DataException("Job timeout exception, exportJob: " + exportId + ", run longer than " + waitTimeout + " seconds");
|
252
252
|
}
|
253
253
|
}
|
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.3
|
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-25 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
@@ -90,9 +90,9 @@ files:
|
|
90
90
|
- src/main/java/org/embulk/input/marketo/rest/RecordPagingIterable.java
|
91
91
|
- src/test/java/org/embulk/input/marketo/TestMarketoInputPlugin.java
|
92
92
|
- src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java
|
93
|
+
- classpath/embulk-input-marketo-0.5.7.alpha.3.jar
|
93
94
|
- classpath/jetty-http-9.2.14.v20151106.jar
|
94
95
|
- classpath/embulk-base-restclient-0.5.3.jar
|
95
|
-
- classpath/embulk-input-marketo-0.5.7.alpha.2.jar
|
96
96
|
- classpath/jetty-client-9.2.14.v20151106.jar
|
97
97
|
- classpath/jetty-util-9.2.14.v20151106.jar
|
98
98
|
- classpath/embulk-util-retryhelper-jetty92-0.5.3.jar
|