embulk-input-marketo 0.6.13 → 0.6.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/CHANGELOG.md +9 -0
- data/build.gradle +1 -1
- data/src/main/java/org/embulk/input/marketo/delegate/ActivityBulkExtractInputPlugin.java +1 -2
- data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectInputPlugin.java +1 -1
- data/src/main/java/org/embulk/input/marketo/delegate/CustomObjectResponseMapperBuilder.java +1 -0
- data/src/main/java/org/embulk/input/marketo/delegate/LeadBulkExtractInputPlugin.java +1 -2
- data/src/main/java/org/embulk/input/marketo/delegate/ProgramInputPlugin.java +0 -1
- data/src/main/java/org/embulk/input/marketo/rest/MarketoBaseRestClient.java +38 -4
- data/src/test/java/org/embulk/input/marketo/delegate/CustomObjectInputPluginTest.java +1 -0
- data/src/test/java/org/embulk/input/marketo/delegate/ProgramInputPluginTest.java +7 -9
- data/src/test/java/org/embulk/input/marketo/rest/MarketoBaseRestClientTest.java +83 -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: a1ecb21401432881f5191869093f9e26d7eecd77
|
4
|
+
data.tar.gz: 80bce389f5f836747a900ce87d2d637125df6f0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 290ecc3ed678f765358615a0fb2e71bc61142999cf5cae9afa1c4aa60619df2e37778a884201f1505c478aef1d29311afd460f16d705785fc71a4f46f3f9c50c
|
7
|
+
data.tar.gz: 03e2c3625ade8587e3c1730f8ce3a6ffb3baa77195c7a26030fe988cdd22486150862e759c752f27c91ec58cdb20fb2b76441ff46f289936b38128d4b2de202c
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 0.6.15 - 2019-09-20
|
2
|
+
* [enhancement] Raise RuntimeException for temp file error [#94](https://github.com/treasure-data/embulk-input-marketo/pull/94)
|
3
|
+
|
4
|
+
## 0.6.14 - 2019-08-19
|
5
|
+
* [enhancement] Improve exception handling [#93](https://github.com/treasure-data/embulk-input-marketo/pull/93)
|
6
|
+
|
7
|
+
## 0.6.13 - 2019-01-21
|
8
|
+
* [enhance] Add more error code to retry [#91](https://github.com/treasure-data/embulk-input-marketo/pull/91)
|
9
|
+
|
1
10
|
## 0.6.12 - 2018-11-09
|
2
11
|
* [enhance] Implement Custom Object [#90](https://github.com/treasure-data/embulk-input-marketo/pull/90)
|
3
12
|
|
data/build.gradle
CHANGED
@@ -42,8 +42,7 @@ public class ActivityBulkExtractInputPlugin extends MarketoBaseBulkExtractInputP
|
|
42
42
|
return new FileInputStream(service.extractAllActivity(fromDate.toDate(), toDate.toDate(), task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond()));
|
43
43
|
}
|
44
44
|
catch (FileNotFoundException e) {
|
45
|
-
|
46
|
-
throw new DataException("Error when trying to extract activity");
|
45
|
+
throw new RuntimeException("Exception when trying to extract activity", e);
|
47
46
|
}
|
48
47
|
}
|
49
48
|
|
@@ -15,6 +15,7 @@ import org.embulk.input.marketo.MarketoUtils;
|
|
15
15
|
import org.embulk.input.marketo.rest.MarketoRestClient;
|
16
16
|
import org.embulk.spi.Exec;
|
17
17
|
import org.slf4j.Logger;
|
18
|
+
|
18
19
|
import java.util.Iterator;
|
19
20
|
|
20
21
|
public class CustomObjectInputPlugin extends MarketoBaseInputPluginDelegate<CustomObjectInputPlugin.PluginTask>
|
@@ -71,5 +72,4 @@ public class CustomObjectInputPlugin extends MarketoBaseInputPluginDelegate<Cust
|
|
71
72
|
return customObjectResponseMapperBuilder.buildServiceResponseMapper(task);
|
72
73
|
}
|
73
74
|
}
|
74
|
-
|
75
75
|
}
|
@@ -52,8 +52,7 @@ public class LeadBulkExtractInputPlugin extends MarketoBaseBulkExtractInputPlugi
|
|
52
52
|
return new FileInputStream(service.extractLead(fromDate.toDate(), toDate.toDate(), fieldNames, task.getIncrementalColumn().orNull(), task.getPollingIntervalSecond(), task.getBulkJobTimeoutSecond()));
|
53
53
|
}
|
54
54
|
catch (FileNotFoundException e) {
|
55
|
-
|
56
|
-
throw new DataException("Error when extract lead");
|
55
|
+
throw new RuntimeException("File not found", e);
|
57
56
|
}
|
58
57
|
}
|
59
58
|
|
@@ -179,7 +179,6 @@ public class ProgramInputPlugin extends MarketoBaseInputPluginDelegate<ProgramIn
|
|
179
179
|
ConfigDiff configDiff = super.buildConfigDiff(task, schema, taskCount, taskReports);
|
180
180
|
// set next next earliestUpdatedAt, latestUpdatedAt
|
181
181
|
if (task.getQueryBy().isPresent() && task.getQueryBy().get() == QueryBy.DATE_RANGE && task.getIncremental()) {
|
182
|
-
|
183
182
|
DateTime earliest = new DateTime(task.getEarliestUpdatedAt().get());
|
184
183
|
DateTime latest = new DateTime(task.getLatestUpdatedAt().get());
|
185
184
|
|
@@ -5,11 +5,13 @@ import com.google.common.annotations.VisibleForTesting;
|
|
5
5
|
import com.google.common.collect.ArrayListMultimap;
|
6
6
|
import com.google.common.collect.Multimap;
|
7
7
|
import org.eclipse.jetty.client.HttpClient;
|
8
|
+
import org.eclipse.jetty.client.HttpResponseException;
|
8
9
|
import org.eclipse.jetty.client.api.ContentProvider;
|
9
10
|
import org.eclipse.jetty.client.api.Request;
|
10
11
|
import org.eclipse.jetty.client.api.Response;
|
11
12
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
12
13
|
import org.eclipse.jetty.http.HttpMethod;
|
14
|
+
import org.embulk.config.ConfigException;
|
13
15
|
import org.embulk.input.marketo.exception.MarketoAPIException;
|
14
16
|
import org.embulk.input.marketo.model.MarketoAccessTokenResponse;
|
15
17
|
import org.embulk.input.marketo.model.MarketoError;
|
@@ -72,7 +74,7 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
72
74
|
|
73
75
|
private void renewAccessToken()
|
74
76
|
{
|
75
|
-
accessToken =
|
77
|
+
accessToken = getAccessTokenWithWrappedException();
|
76
78
|
}
|
77
79
|
|
78
80
|
@VisibleForTesting
|
@@ -81,7 +83,7 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
81
83
|
if (accessToken == null) {
|
82
84
|
synchronized (this) {
|
83
85
|
if (accessToken == null) {
|
84
|
-
accessToken =
|
86
|
+
accessToken = getAccessTokenWithWrappedException();
|
85
87
|
}
|
86
88
|
}
|
87
89
|
}
|
@@ -146,7 +148,7 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
146
148
|
|
147
149
|
protected <T> T doGet(final String target, final Map<String, String> headers, final Multimap<String, String> params, Jetty92ResponseReader<T> responseReader)
|
148
150
|
{
|
149
|
-
return
|
151
|
+
return doRequestWithWrappedException(target, HttpMethod.GET, headers, params, null, responseReader);
|
150
152
|
}
|
151
153
|
|
152
154
|
protected <T> T doPost(final String target, final Map<String, String> headers, final Multimap<String, String> params, final String content, Jetty92ResponseReader<T> responseReader)
|
@@ -160,7 +162,39 @@ public class MarketoBaseRestClient implements AutoCloseable
|
|
160
162
|
|
161
163
|
protected <T> T doPost(final String target, final Map<String, String> headers, final Multimap<String, String> params, Jetty92ResponseReader<T> responseReader, final ContentProvider content)
|
162
164
|
{
|
163
|
-
return
|
165
|
+
return doRequestWithWrappedException(target, HttpMethod.POST, headers, params, content, responseReader);
|
166
|
+
}
|
167
|
+
|
168
|
+
private String getAccessTokenWithWrappedException()
|
169
|
+
{
|
170
|
+
try {
|
171
|
+
return requestAccessToken();
|
172
|
+
}
|
173
|
+
catch (Exception e) {
|
174
|
+
if (e instanceof HttpResponseException) {
|
175
|
+
throw new ConfigException(e.getMessage());
|
176
|
+
}
|
177
|
+
if (e.getCause() instanceof HttpResponseException) {
|
178
|
+
throw new ConfigException(e.getCause().getMessage());
|
179
|
+
}
|
180
|
+
throw e;
|
181
|
+
}
|
182
|
+
}
|
183
|
+
|
184
|
+
private <T> T doRequestWithWrappedException(final String target, final HttpMethod method, final Map<String, String> headers, final Multimap<String, String> params, final ContentProvider contentProvider, Jetty92ResponseReader<T> responseReader)
|
185
|
+
{
|
186
|
+
try {
|
187
|
+
return doRequest(target, method, headers, params, contentProvider, responseReader);
|
188
|
+
}
|
189
|
+
catch (Exception e) {
|
190
|
+
if (e instanceof MarketoAPIException || e instanceof HttpResponseException) {
|
191
|
+
throw new DataException(e.getMessage());
|
192
|
+
}
|
193
|
+
if (e.getCause() instanceof MarketoAPIException || e.getCause() instanceof HttpResponseException) {
|
194
|
+
throw new DataException(e.getCause().getMessage());
|
195
|
+
}
|
196
|
+
throw e;
|
197
|
+
}
|
164
198
|
}
|
165
199
|
|
166
200
|
protected <T> T doRequest(final String target, final HttpMethod method, final Map<String, String> headers, final Multimap<String, String> params, final ContentProvider contentProvider, Jetty92ResponseReader<T> responseReader)
|
@@ -7,7 +7,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|
7
7
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
8
8
|
import com.google.common.base.Optional;
|
9
9
|
import com.google.common.base.Predicate;
|
10
|
-
|
10
|
+
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
11
11
|
import org.embulk.EmbulkTestRuntime;
|
12
12
|
import org.embulk.base.restclient.ServiceResponseMapper;
|
13
13
|
import org.embulk.base.restclient.record.RecordImporter;
|
@@ -45,11 +45,9 @@ import java.util.List;
|
|
45
45
|
import static org.junit.Assert.assertArrayEquals;
|
46
46
|
import static org.junit.Assert.assertEquals;
|
47
47
|
|
48
|
-
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
|
49
|
-
|
50
48
|
public class ProgramInputPluginTest
|
51
49
|
{
|
52
|
-
private static final DateTimeFormatter
|
50
|
+
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormat.forPattern(MarketoUtils.MARKETO_DATE_SIMPLE_DATE_FORMAT);
|
53
51
|
|
54
52
|
private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();
|
55
53
|
|
@@ -153,7 +151,7 @@ public class ProgramInputPluginTest
|
|
153
151
|
DateTime earliestUpdatedAt = DateTime.now().plusDays(1);
|
154
152
|
DateTime latestUpdatedAt = DateTime.now().minusDays(2);
|
155
153
|
thrown.expect(ConfigException.class);
|
156
|
-
thrown.expectMessage(String.format("`earliest_updated_at` (%s) cannot precede the current date ", earliestUpdatedAt.toString(
|
154
|
+
thrown.expectMessage(String.format("`earliest_updated_at` (%s) cannot precede the current date ", earliestUpdatedAt.toString(DATE_FORMATTER)));
|
157
155
|
ConfigSource config = baseConfig
|
158
156
|
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
159
157
|
.set("earliest_updated_at", Optional.of(earliestUpdatedAt))
|
@@ -168,8 +166,8 @@ public class ProgramInputPluginTest
|
|
168
166
|
DateTime latestUpdatedAt = DateTime.now().minusDays(20);
|
169
167
|
thrown.expect(ConfigException.class);
|
170
168
|
thrown.expectMessage(String.format("Invalid date range. `earliest_updated_at` (%s) cannot precede the `latest_updated_at` (%s).",
|
171
|
-
earliestUpdatedAt.toString(
|
172
|
-
latestUpdatedAt.toString(
|
169
|
+
earliestUpdatedAt.toString(DATE_FORMATTER),
|
170
|
+
latestUpdatedAt.toString(DATE_FORMATTER)));
|
173
171
|
|
174
172
|
ConfigSource config = baseConfig
|
175
173
|
.set("query_by", Optional.of(QueryBy.DATE_RANGE))
|
@@ -218,7 +216,7 @@ public class ProgramInputPluginTest
|
|
218
216
|
String earliestUpdatedAtStr = taskReport.get(String.class, "earliest_updated_at");
|
219
217
|
long duration = taskReport.get(Long.class, "report_duration");
|
220
218
|
assertEquals(duration, reportDuration);
|
221
|
-
assertEquals(earliestUpdatedAtStr, earliestUpdatedAt.toString(
|
219
|
+
assertEquals(earliestUpdatedAtStr, earliestUpdatedAt.toString(DATE_FORMATTER));
|
222
220
|
}
|
223
221
|
|
224
222
|
@Test
|
@@ -239,7 +237,7 @@ public class ProgramInputPluginTest
|
|
239
237
|
String nextErliestUpdatedAt = diff.get(String.class, "earliest_updated_at");
|
240
238
|
|
241
239
|
assertEquals(reportDuration, new Duration(earliestUpdatedAt, latestUpdatedAt).getMillis());
|
242
|
-
assertEquals(nextErliestUpdatedAt, latestUpdatedAt.plusSeconds(1).toString(
|
240
|
+
assertEquals(nextErliestUpdatedAt, latestUpdatedAt.plusSeconds(1).toString(DATE_FORMATTER));
|
243
241
|
}
|
244
242
|
|
245
243
|
@SuppressWarnings("unchecked")
|
@@ -12,10 +12,12 @@ import org.eclipse.jetty.client.api.Response;
|
|
12
12
|
import org.eclipse.jetty.client.util.StringContentProvider;
|
13
13
|
import org.eclipse.jetty.http.HttpMethod;
|
14
14
|
import org.embulk.EmbulkTestRuntime;
|
15
|
+
import org.embulk.config.ConfigException;
|
15
16
|
import org.embulk.input.marketo.exception.MarketoAPIException;
|
16
17
|
import org.embulk.input.marketo.model.MarketoError;
|
17
18
|
import org.embulk.input.marketo.model.MarketoResponse;
|
18
19
|
import org.embulk.spi.DataException;
|
20
|
+
import org.embulk.util.retryhelper.jetty92.Jetty92ClientCreator;
|
19
21
|
import org.embulk.util.retryhelper.jetty92.Jetty92RetryHelper;
|
20
22
|
import org.embulk.util.retryhelper.jetty92.Jetty92SingleRequester;
|
21
23
|
import org.embulk.util.retryhelper.jetty92.StringJetty92ResponseEntityReader;
|
@@ -23,6 +25,7 @@ import org.junit.Assert;
|
|
23
25
|
import org.junit.Before;
|
24
26
|
import org.junit.Rule;
|
25
27
|
import org.junit.Test;
|
28
|
+
import org.junit.function.ThrowingRunnable;
|
26
29
|
import org.mockito.ArgumentCaptor;
|
27
30
|
import org.mockito.Mockito;
|
28
31
|
|
@@ -119,6 +122,86 @@ public class MarketoBaseRestClientTest
|
|
119
122
|
Assert.fail();
|
120
123
|
}
|
121
124
|
|
125
|
+
@Test
|
126
|
+
public void testGetAccessTokenThrowHttpResponseException() throws Exception
|
127
|
+
{
|
128
|
+
HttpClient client = Mockito.mock(HttpClient.class);
|
129
|
+
|
130
|
+
Jetty92ClientCreator clientCreator = Mockito.mock(Jetty92ClientCreator.class);
|
131
|
+
Mockito.doReturn(client).when(clientCreator).createAndStart();
|
132
|
+
|
133
|
+
Request request = Mockito.mock(Request.class);
|
134
|
+
Mockito.doReturn(request).when(client).newRequest(Mockito.anyString());
|
135
|
+
Mockito.doReturn(request).when(request).method(HttpMethod.GET);
|
136
|
+
|
137
|
+
HttpResponseException exception = new HttpResponseException("{\"error\":\"invalid_client\",\"error_description\":\"Bad client credentials\"}", Mockito.mock(Response.class));
|
138
|
+
Mockito.doThrow(exception).when(request).send(Mockito.any(Response.Listener.class));
|
139
|
+
|
140
|
+
Jetty92RetryHelper retryHelper = new Jetty92RetryHelper(1, 1, 1, clientCreator);
|
141
|
+
final MarketoBaseRestClient restClient = new MarketoBaseRestClient("identityEndPoint", "clientId", "clientSecret", MARKETO_LIMIT_INTERVAL_MILIS, 1000, retryHelper);
|
142
|
+
|
143
|
+
// calling method should wrap the HttpResponseException by ConfigException
|
144
|
+
Assert.assertThrows(ConfigException.class, new ThrowingRunnable()
|
145
|
+
{
|
146
|
+
@Override
|
147
|
+
public void run() throws Throwable
|
148
|
+
{
|
149
|
+
restClient.getAccessToken();
|
150
|
+
}
|
151
|
+
});
|
152
|
+
}
|
153
|
+
|
154
|
+
@Test
|
155
|
+
public void tetDoGetThrowHttpResponseException() throws Exception
|
156
|
+
{
|
157
|
+
final MarketoBaseRestClient client = doRequestWithWrapper(HttpMethod.GET);
|
158
|
+
// calling method should wrap the HttpResponseException by DataException
|
159
|
+
Assert.assertThrows(DataException.class, new ThrowingRunnable()
|
160
|
+
{
|
161
|
+
@Override
|
162
|
+
public void run() throws Throwable
|
163
|
+
{
|
164
|
+
client.doGet("test_target", null, null, new MarketoResponseJetty92EntityReader<String>(1000));
|
165
|
+
}
|
166
|
+
});
|
167
|
+
}
|
168
|
+
|
169
|
+
@Test
|
170
|
+
public void tetDoPostThrowHttpResponseException() throws Exception
|
171
|
+
{
|
172
|
+
final MarketoBaseRestClient client = doRequestWithWrapper(HttpMethod.POST);
|
173
|
+
// calling method should wrap the HttpResponseException by DataException
|
174
|
+
Assert.assertThrows(DataException.class, new ThrowingRunnable()
|
175
|
+
{
|
176
|
+
@Override
|
177
|
+
public void run() throws Throwable
|
178
|
+
{
|
179
|
+
client.doPost("test_target", null, null, "{\"any\": \"any\"}", new MarketoResponseJetty92EntityReader<String>(1000));
|
180
|
+
}
|
181
|
+
});
|
182
|
+
}
|
183
|
+
|
184
|
+
private MarketoBaseRestClient doRequestWithWrapper(HttpMethod method) throws Exception
|
185
|
+
{
|
186
|
+
HttpClient client = Mockito.mock(HttpClient.class);
|
187
|
+
|
188
|
+
Jetty92ClientCreator clientCreator = Mockito.mock(Jetty92ClientCreator.class);
|
189
|
+
Mockito.doReturn(client).when(clientCreator).createAndStart();
|
190
|
+
|
191
|
+
Request request = Mockito.mock(Request.class);
|
192
|
+
Mockito.doReturn(request).when(client).newRequest(Mockito.anyString());
|
193
|
+
Mockito.doReturn(request).when(request).method(method);
|
194
|
+
|
195
|
+
HttpResponseException exception = new HttpResponseException("{\"error\":\"1035\",\"error_description\":\"Unsupported filter type for target subscription: updatedAt\"}", Mockito.mock(Response.class));
|
196
|
+
Mockito.doThrow(exception).when(request).send(Mockito.any(Response.Listener.class));
|
197
|
+
|
198
|
+
Jetty92RetryHelper retryHelper = new Jetty92RetryHelper(1, 1, 1, clientCreator);
|
199
|
+
final MarketoBaseRestClient restClient = Mockito.spy(new MarketoBaseRestClient("identityEndPoint", "clientId", "clientSecret", MARKETO_LIMIT_INTERVAL_MILIS, 1000, retryHelper));
|
200
|
+
Mockito.doReturn("test_access_token").when(restClient).getAccessToken();
|
201
|
+
|
202
|
+
return restClient;
|
203
|
+
}
|
204
|
+
|
122
205
|
@Test
|
123
206
|
public void testDoPost() throws Exception
|
124
207
|
{
|
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.6.
|
4
|
+
version: 0.6.15
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- uu59
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2019-
|
13
|
+
date: 2019-09-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
@@ -137,9 +137,9 @@ files:
|
|
137
137
|
- src/test/resources/fixtures/program_response.json
|
138
138
|
- classpath/jetty-io-9.2.14.v20151106.jar
|
139
139
|
- classpath/jetty-util-9.2.14.v20151106.jar
|
140
|
+
- classpath/embulk-input-marketo-0.6.15.jar
|
140
141
|
- classpath/jetty-http-9.2.14.v20151106.jar
|
141
142
|
- classpath/jetty-client-9.2.14.v20151106.jar
|
142
|
-
- classpath/embulk-input-marketo-0.6.13.jar
|
143
143
|
- classpath/embulk-base-restclient-0.5.3.jar
|
144
144
|
- classpath/embulk-util-retryhelper-jetty92-0.5.3.jar
|
145
145
|
homepage: https://github.com/treasure-data/embulk-input-marketo
|