embulk-input-http 0.0.15 → 0.0.17
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/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
|
}
|