embulk-input-http 0.0.15 → 0.0.17
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +10 -9
- data/build.gradle +17 -5
- data/classpath/commons-io-2.5.jar +0 -0
- data/classpath/embulk-input-http-0.0.17.jar +0 -0
- data/embulk-input-http.gemspec +17 -0
- data/example/json-example.yml +1 -0
- data/src/main/java/org/embulk/input/http/{BasicAuthConfig.java → BasicAuthOption.java} +14 -10
- data/src/main/java/org/embulk/input/http/HttpFileInputPlugin.java +125 -64
- data/src/main/java/org/embulk/input/http/{PagerConfig.java → PagerOption.java} +26 -17
- data/src/main/java/org/embulk/input/http/{ParamsConfig.java → ParamsOption.java} +32 -24
- data/src/main/java/org/embulk/input/http/{QueryConfig.java → QueryOption.java} +55 -34
- data/src/main/java/org/embulk/input/http/RetryableHandler.java +23 -21
- data/src/test/java/org/embulk/input/http/{TestPagerConfig.java → TestPagerOption.java} +11 -9
- data/src/test/java/org/embulk/input/http/{TestParamsConfig.java → TestParamsOption.java} +31 -27
- data/src/test/java/org/embulk/input/http/{TestQueryConfig.java → TestQueryOption.java} +34 -27
- metadata +12 -10
- data/classpath/embulk-input-http-0.0.15.jar +0 -0
@@ -7,8 +7,8 @@ import com.google.common.base.Optional;
|
|
7
7
|
import java.util.ArrayList;
|
8
8
|
import java.util.List;
|
9
9
|
|
10
|
-
public class
|
11
|
-
|
10
|
+
public class PagerOption
|
11
|
+
{
|
12
12
|
private final String fromParam;
|
13
13
|
private final Optional<String> toParam;
|
14
14
|
private final int start;
|
@@ -16,11 +16,12 @@ public class PagerConfig {
|
|
16
16
|
private final int step;
|
17
17
|
|
18
18
|
@JsonCreator
|
19
|
-
public
|
19
|
+
public PagerOption(@JsonProperty("from_param") String fromParam,
|
20
20
|
@JsonProperty("to_param") Optional<String> toParam,
|
21
21
|
@JsonProperty("start") Optional<Integer> start,
|
22
22
|
@JsonProperty("pages") int pages,
|
23
|
-
@JsonProperty("step") Optional<Integer> step)
|
23
|
+
@JsonProperty("step") Optional<Integer> step)
|
24
|
+
{
|
24
25
|
this.fromParam = fromParam;
|
25
26
|
this.toParam = toParam;
|
26
27
|
this.start = start.or(0);
|
@@ -28,18 +29,20 @@ public class PagerConfig {
|
|
28
29
|
this.step = step.or(1);
|
29
30
|
}
|
30
31
|
|
31
|
-
public List<List<
|
32
|
-
|
32
|
+
public List<List<QueryOption.Query>> expand()
|
33
|
+
{
|
34
|
+
List<List<QueryOption.Query>> queries = new ArrayList<>();
|
33
35
|
int p = 1;
|
34
36
|
int index = start;
|
35
37
|
while (p <= pages) {
|
36
|
-
List<
|
37
|
-
one.add(new
|
38
|
+
List<QueryOption.Query> one = new ArrayList<>();
|
39
|
+
one.add(new QueryOption.Query(fromParam, Integer.toString(index)));
|
38
40
|
if (toParam.isPresent()) {
|
39
41
|
int t = index + step - 1;
|
40
|
-
one.add(new
|
42
|
+
one.add(new QueryOption.Query(toParam.get(), Integer.toString(t)));
|
41
43
|
index = t + 1;
|
42
|
-
}
|
44
|
+
}
|
45
|
+
else {
|
43
46
|
index += step;
|
44
47
|
}
|
45
48
|
queries.add(one);
|
@@ -49,33 +52,39 @@ public class PagerConfig {
|
|
49
52
|
}
|
50
53
|
|
51
54
|
@JsonProperty("from_param")
|
52
|
-
public String getFromParam()
|
55
|
+
public String getFromParam()
|
56
|
+
{
|
53
57
|
return fromParam;
|
54
58
|
}
|
55
59
|
|
56
60
|
@JsonProperty("to_param")
|
57
|
-
public Optional<String> getToParam()
|
61
|
+
public Optional<String> getToParam()
|
62
|
+
{
|
58
63
|
return toParam;
|
59
64
|
}
|
60
65
|
|
61
66
|
@JsonProperty("start")
|
62
|
-
public int getStart()
|
67
|
+
public int getStart()
|
68
|
+
{
|
63
69
|
return start;
|
64
70
|
}
|
65
71
|
|
66
72
|
@JsonProperty("pages")
|
67
|
-
public int getPages()
|
73
|
+
public int getPages()
|
74
|
+
{
|
68
75
|
return pages;
|
69
76
|
}
|
70
77
|
|
71
78
|
@JsonProperty("step")
|
72
|
-
public int getStep()
|
79
|
+
public int getStep()
|
80
|
+
{
|
73
81
|
return step;
|
74
82
|
}
|
75
83
|
|
76
84
|
@Override
|
77
|
-
public String toString()
|
78
|
-
|
85
|
+
public String toString()
|
86
|
+
{
|
87
|
+
return "PagerOption{" +
|
79
88
|
"fromParam='" + fromParam + '\'' +
|
80
89
|
", toParam=" + toParam +
|
81
90
|
", start=" + start +
|
@@ -8,44 +8,49 @@ import com.google.common.base.Optional;
|
|
8
8
|
import java.util.ArrayList;
|
9
9
|
import java.util.List;
|
10
10
|
|
11
|
-
public class
|
12
|
-
|
13
|
-
private final List<
|
11
|
+
public class ParamsOption
|
12
|
+
{
|
13
|
+
private final List<QueryOption> queries;
|
14
14
|
|
15
15
|
@JsonCreator
|
16
|
-
public
|
16
|
+
public ParamsOption(List<QueryOption> queries)
|
17
|
+
{
|
17
18
|
this.queries = queries;
|
18
19
|
}
|
19
20
|
|
20
21
|
@JsonValue
|
21
|
-
public List<
|
22
|
+
public List<QueryOption> getQueries()
|
23
|
+
{
|
22
24
|
return queries;
|
23
25
|
}
|
24
26
|
|
25
|
-
public List<List<
|
26
|
-
|
27
|
-
|
27
|
+
public List<List<QueryOption.Query>> generateQueries(Optional<PagerOption> pagerOption)
|
28
|
+
{
|
29
|
+
List<List<QueryOption.Query>> base = new ArrayList<>(queries.size());
|
30
|
+
for (QueryOption p : queries) {
|
28
31
|
base.add(p.expand());
|
29
32
|
}
|
30
33
|
|
31
34
|
int productSize = 1;
|
32
35
|
int baseSize = base.size();
|
33
|
-
for (int i = 0; i < baseSize; productSize *= base.get(i).size(), i++)
|
36
|
+
for (int i = 0; i < baseSize; productSize *= base.get(i).size(), i++) {
|
37
|
+
}
|
34
38
|
|
35
|
-
List<List<
|
39
|
+
List<List<QueryOption.Query>> expands = new ArrayList<>(productSize);
|
36
40
|
for (int i = 0; i < productSize; i++) {
|
37
41
|
int j = 1;
|
38
|
-
List<
|
39
|
-
for (List<
|
40
|
-
|
42
|
+
List<QueryOption.Query> one = new ArrayList<>();
|
43
|
+
for (List<QueryOption.Query> list : base) {
|
44
|
+
QueryOption.Query pc = list.get((i / j) % list.size());
|
41
45
|
one.add(pc);
|
42
46
|
j *= list.size();
|
43
47
|
}
|
44
|
-
if (
|
45
|
-
for (List<
|
48
|
+
if (pagerOption.isPresent()) {
|
49
|
+
for (List<QueryOption.Query> q : pagerOption.get().expand()) {
|
46
50
|
expands.add(copyAndConcat(one, q));
|
47
51
|
}
|
48
|
-
}
|
52
|
+
}
|
53
|
+
else {
|
49
54
|
expands.add(one);
|
50
55
|
}
|
51
56
|
}
|
@@ -54,26 +59,29 @@ public class ParamsConfig {
|
|
54
59
|
}
|
55
60
|
|
56
61
|
@Override
|
57
|
-
public boolean equals(Object obj)
|
62
|
+
public boolean equals(Object obj)
|
63
|
+
{
|
58
64
|
if (this == obj) {
|
59
65
|
return true;
|
60
66
|
}
|
61
|
-
if (!(obj instanceof
|
67
|
+
if (!(obj instanceof ParamsOption)) {
|
62
68
|
return false;
|
63
69
|
}
|
64
|
-
|
70
|
+
ParamsOption other = (ParamsOption) obj;
|
65
71
|
return Objects.equal(queries, other.queries);
|
66
72
|
}
|
67
73
|
|
68
74
|
@Override
|
69
|
-
public int hashCode()
|
75
|
+
public int hashCode()
|
76
|
+
{
|
70
77
|
return Objects.hashCode(queries);
|
71
78
|
}
|
72
79
|
|
73
|
-
private List<
|
74
|
-
|
75
|
-
|
76
|
-
|
80
|
+
private List<QueryOption.Query> copyAndConcat(List<QueryOption.Query>... srcs)
|
81
|
+
{
|
82
|
+
List<QueryOption.Query> dest = new ArrayList<>();
|
83
|
+
for (List<QueryOption.Query> src : srcs) {
|
84
|
+
for (QueryOption.Query q : src) {
|
77
85
|
dest.add(q.copy());
|
78
86
|
}
|
79
87
|
}
|
@@ -9,26 +9,27 @@ import java.util.ArrayList;
|
|
9
9
|
import java.util.Arrays;
|
10
10
|
import java.util.List;
|
11
11
|
|
12
|
-
public class
|
13
|
-
|
12
|
+
public class QueryOption
|
13
|
+
{
|
14
14
|
private final String name;
|
15
15
|
private final Optional<String> value;
|
16
16
|
private final Optional<List<String>> values;
|
17
17
|
private final boolean expand;
|
18
18
|
|
19
19
|
@JsonCreator
|
20
|
-
public
|
21
|
-
@JsonProperty("name") String name,
|
20
|
+
public QueryOption(@JsonProperty("name") String name,
|
22
21
|
@JsonProperty("value") Optional<String> value,
|
23
22
|
@JsonProperty("values") Optional<List<String>> values,
|
24
|
-
@JsonProperty("expand") boolean expand)
|
23
|
+
@JsonProperty("expand") boolean expand)
|
24
|
+
{
|
25
25
|
this.name = name;
|
26
26
|
this.value = value;
|
27
27
|
this.values = values;
|
28
28
|
this.expand = expand;
|
29
29
|
}
|
30
30
|
|
31
|
-
public List<Query> expand()
|
31
|
+
public List<Query> expand()
|
32
|
+
{
|
32
33
|
List<Query> dest;
|
33
34
|
if (value.isPresent()) {
|
34
35
|
if (expand) {
|
@@ -37,102 +38,119 @@ public class QueryConfig {
|
|
37
38
|
for (String s : expanded) {
|
38
39
|
dest.add(new Query(name, s));
|
39
40
|
}
|
40
|
-
}
|
41
|
+
}
|
42
|
+
else {
|
41
43
|
dest = new ArrayList<>(1);
|
42
44
|
dest.add(new Query(name, value.get()));
|
43
45
|
}
|
44
|
-
}
|
46
|
+
}
|
47
|
+
else if (values.isPresent()) {
|
45
48
|
if (expand) {
|
46
49
|
dest = new ArrayList<>(values.get().size());
|
47
50
|
for (String s : values.get()) {
|
48
51
|
dest.add(new Query(name, s));
|
49
52
|
}
|
50
|
-
}
|
53
|
+
}
|
54
|
+
else {
|
51
55
|
dest = new ArrayList<>(1);
|
52
56
|
final String[] valueArr = values.get().toArray(new String[values.get().size()]);
|
53
57
|
dest.add(new Query(name, valueArr));
|
54
58
|
}
|
55
|
-
}
|
59
|
+
}
|
60
|
+
else {
|
56
61
|
throw new IllegalArgumentException("value or values must be specified to 'params'");
|
57
62
|
}
|
58
63
|
return dest;
|
59
64
|
}
|
60
65
|
|
61
66
|
@JsonProperty("name")
|
62
|
-
public String getName()
|
67
|
+
public String getName()
|
68
|
+
{
|
63
69
|
return name;
|
64
70
|
}
|
65
71
|
|
66
72
|
@JsonProperty("value")
|
67
|
-
public Optional<String> getValue()
|
73
|
+
public Optional<String> getValue()
|
74
|
+
{
|
68
75
|
return value;
|
69
76
|
}
|
70
77
|
|
71
78
|
@JsonProperty("expand")
|
72
|
-
public boolean isExpand()
|
79
|
+
public boolean isExpand()
|
80
|
+
{
|
73
81
|
return expand;
|
74
82
|
}
|
75
83
|
|
76
84
|
@Override
|
77
|
-
public boolean equals(Object obj)
|
85
|
+
public boolean equals(Object obj)
|
86
|
+
{
|
78
87
|
if (this == obj) {
|
79
88
|
return true;
|
80
89
|
}
|
81
|
-
if (!(obj instanceof
|
90
|
+
if (!(obj instanceof QueryOption)) {
|
82
91
|
return false;
|
83
92
|
}
|
84
|
-
|
93
|
+
QueryOption other = (QueryOption) obj;
|
85
94
|
return Objects.equal(this.name, other.name) &&
|
86
95
|
Objects.equal(value, other.value) &&
|
87
96
|
Objects.equal(expand, other.expand);
|
88
97
|
}
|
89
98
|
|
90
99
|
@Override
|
91
|
-
public int hashCode()
|
100
|
+
public int hashCode()
|
101
|
+
{
|
92
102
|
return Objects.hashCode(name, value, expand);
|
93
103
|
}
|
94
104
|
|
95
105
|
@Override
|
96
|
-
public String toString()
|
106
|
+
public String toString()
|
107
|
+
{
|
97
108
|
return String.format("ParameterConfig[%s, %s, %s]",
|
98
109
|
getName(), getValue(), isExpand());
|
99
110
|
}
|
100
111
|
|
101
|
-
public static class Query
|
112
|
+
public static class Query
|
113
|
+
{
|
102
114
|
private final String name;
|
103
115
|
private final String[] values;
|
104
116
|
|
105
|
-
public Query(
|
106
|
-
@JsonProperty("
|
107
|
-
|
117
|
+
public Query(@JsonProperty("name") String name,
|
118
|
+
@JsonProperty("values") String... values)
|
119
|
+
{
|
108
120
|
this.name = name;
|
109
121
|
this.values = values;
|
110
122
|
}
|
111
123
|
|
112
|
-
public String getName()
|
124
|
+
public String getName()
|
125
|
+
{
|
113
126
|
return name;
|
114
127
|
}
|
115
128
|
|
116
|
-
public String[] getValues()
|
129
|
+
public String[] getValues()
|
130
|
+
{
|
117
131
|
return values;
|
118
132
|
}
|
119
133
|
|
120
|
-
public Query copy()
|
134
|
+
public Query copy()
|
135
|
+
{
|
121
136
|
return new Query(this.name, Arrays.copyOf(this.values, this.values.length));
|
122
137
|
}
|
123
138
|
}
|
124
139
|
|
125
|
-
private static class BraceExpansion
|
126
|
-
|
127
|
-
public static List<String> expand(String s)
|
140
|
+
private static class BraceExpansion
|
141
|
+
{
|
142
|
+
public static List<String> expand(String s)
|
143
|
+
{
|
128
144
|
return expandRecursive("", s, "", new ArrayList<String>());
|
129
145
|
}
|
130
146
|
|
131
147
|
private static List<String> expandRecursive(String prefix, String s,
|
132
|
-
String suffix, List<String> dest)
|
133
|
-
|
148
|
+
String suffix, List<String> dest)
|
149
|
+
{
|
150
|
+
// used the code below as reference.
|
134
151
|
// http://rosettacode.org/wiki/Brace_expansion#Java
|
135
|
-
int i1 = -1
|
152
|
+
int i1 = -1;
|
153
|
+
int i2 = 0;
|
136
154
|
String noEscape = s.replaceAll("([\\\\]{2}|[\\\\][,}{])", " ");
|
137
155
|
StringBuilder sb = null;
|
138
156
|
|
@@ -146,7 +164,8 @@ public class QueryConfig {
|
|
146
164
|
depth = (c == '}') ? --depth : depth;
|
147
165
|
if (c == ',' && depth == 1) {
|
148
166
|
sb.setCharAt(i2, '\u0000');
|
149
|
-
}
|
167
|
+
}
|
168
|
+
else if (c == '}' && depth == 0 && sb.indexOf("\u0000") != -1) {
|
150
169
|
break outer;
|
151
170
|
}
|
152
171
|
}
|
@@ -155,12 +174,14 @@ public class QueryConfig {
|
|
155
174
|
if (i1 == -1) {
|
156
175
|
if (suffix.length() > 0) {
|
157
176
|
expandRecursive(prefix + s, suffix, "", dest);
|
158
|
-
}
|
177
|
+
}
|
178
|
+
else {
|
159
179
|
final String out = String.format("%s%s%s", prefix, s, suffix).
|
160
180
|
replaceAll("[\\\\]{2}", "\\").replaceAll("[\\\\]([,}{])", "$1");
|
161
181
|
dest.add(out);
|
162
182
|
}
|
163
|
-
}
|
183
|
+
}
|
184
|
+
else {
|
164
185
|
for (String m : sb.substring(i1 + 1, i2).split("\u0000", -1)) {
|
165
186
|
expandRecursive(prefix + s.substring(0, i1), m, s.substring(i2 + 1) + suffix, dest);
|
166
187
|
}
|
@@ -11,41 +11,40 @@ import org.embulk.spi.util.RetryExecutor;
|
|
11
11
|
import org.slf4j.Logger;
|
12
12
|
|
13
13
|
import javax.net.ssl.SSLException;
|
14
|
+
|
14
15
|
import java.io.IOException;
|
15
16
|
import java.io.InterruptedIOException;
|
16
17
|
import java.net.UnknownHostException;
|
17
18
|
import java.util.List;
|
18
19
|
|
19
|
-
public class RetryableHandler implements RetryExecutor.Retryable
|
20
|
-
|
20
|
+
public class RetryableHandler implements RetryExecutor.Retryable
|
21
|
+
{
|
21
22
|
protected final Logger logger = Exec.getLogger(getClass());
|
22
23
|
|
23
|
-
private static List<Class<? extends IOException>>
|
24
|
+
private static final List<Class<? extends IOException>> NOT_RETRIABLE_CLASSES = ImmutableList.of(UnknownHostException.class,
|
25
|
+
InterruptedIOException.class, SSLException.class);
|
24
26
|
|
25
27
|
private final HttpClient client;
|
26
28
|
private final HttpRequestBase request;
|
27
29
|
private HttpResponse response;
|
28
30
|
|
29
|
-
|
30
|
-
|
31
|
-
classes.add(UnknownHostException.class).
|
32
|
-
add(InterruptedIOException.class).
|
33
|
-
add(SSLException.class);
|
34
|
-
NOT_RETRIABLE_CLAASSES = classes.build();
|
35
|
-
}
|
36
|
-
|
37
|
-
public RetryableHandler(HttpClient client, HttpRequestBase request) {
|
31
|
+
public RetryableHandler(HttpClient client, HttpRequestBase request)
|
32
|
+
{
|
38
33
|
this.client = client;
|
39
34
|
this.request = request;
|
40
35
|
}
|
41
36
|
|
42
|
-
public HttpResponse getResponse()
|
37
|
+
public HttpResponse getResponse()
|
38
|
+
{
|
43
39
|
return response;
|
44
40
|
}
|
45
41
|
|
46
42
|
@Override
|
47
|
-
public Object call() throws Exception
|
48
|
-
|
43
|
+
public Object call() throws Exception
|
44
|
+
{
|
45
|
+
if (response != null) {
|
46
|
+
throw new IllegalStateException("response is already set");
|
47
|
+
}
|
49
48
|
HttpResponse response = client.execute(request);
|
50
49
|
statusIsOkOrThrow(response);
|
51
50
|
this.response = response;
|
@@ -53,8 +52,9 @@ public class RetryableHandler implements RetryExecutor.Retryable {
|
|
53
52
|
}
|
54
53
|
|
55
54
|
@Override
|
56
|
-
public boolean isRetryableException(Exception exception)
|
57
|
-
|
55
|
+
public boolean isRetryableException(Exception exception)
|
56
|
+
{
|
57
|
+
if (NOT_RETRIABLE_CLASSES.contains(exception.getClass())) {
|
58
58
|
logger.error(String.format("'%s' is not retriable", exception.getClass()));
|
59
59
|
return false;
|
60
60
|
}
|
@@ -63,7 +63,8 @@ public class RetryableHandler implements RetryExecutor.Retryable {
|
|
63
63
|
|
64
64
|
@Override
|
65
65
|
public void onRetry(Exception exception, int retryCount, int retryLimit, int retryWait)
|
66
|
-
throws RetryExecutor.RetryGiveupException
|
66
|
+
throws RetryExecutor.RetryGiveupException
|
67
|
+
{
|
67
68
|
logger.warn("retrying {}/{} after {} seconds. Message: {}",
|
68
69
|
retryCount, retryLimit, retryWait / 1000,
|
69
70
|
exception.getMessage());
|
@@ -71,12 +72,14 @@ public class RetryableHandler implements RetryExecutor.Retryable {
|
|
71
72
|
|
72
73
|
@Override
|
73
74
|
public void onGiveup(Exception firstException, Exception lastException)
|
74
|
-
throws RetryExecutor.RetryGiveupException
|
75
|
+
throws RetryExecutor.RetryGiveupException
|
76
|
+
{
|
75
77
|
logger.error("giveup {}", lastException.getMessage());
|
76
78
|
}
|
77
79
|
|
78
80
|
protected void statusIsOkOrThrow(HttpResponse response)
|
79
|
-
throws HttpException, IOException
|
81
|
+
throws HttpException, IOException
|
82
|
+
{
|
80
83
|
int code = response.getStatusLine().getStatusCode();
|
81
84
|
switch (response.getStatusLine().getStatusCode()) {
|
82
85
|
case 200:
|
@@ -86,5 +89,4 @@ public class RetryableHandler implements RetryExecutor.Retryable {
|
|
86
89
|
code, EntityUtils.toString(response.getEntity())));
|
87
90
|
}
|
88
91
|
}
|
89
|
-
|
90
92
|
}
|