embulk-output-td 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/build.gradle +9 -8
  4. data/embulk-output-td.gemspec +1 -1
  5. data/src/main/java/org/embulk/output/td/MsgpackGZFileBuilder.java +11 -12
  6. data/src/main/java/org/embulk/output/td/RecordWriter.java +4 -7
  7. data/src/main/java/org/embulk/output/td/TdOutputPlugin.java +89 -84
  8. data/src/main/java/org/embulk/output/td/writer/FieldWriterSet.java +9 -0
  9. data/src/main/java/org/embulk/output/td/writer/JsonFieldWriter.java +23 -0
  10. data/src/test/java/org/embulk/output/td/TestRecordWriter.java +37 -38
  11. data/src/test/java/org/embulk/output/td/TestTdOutputPlugin.java +53 -49
  12. metadata +9 -30
  13. data/src/main/java/com/treasuredata/api/TdApiClient.java +0 -506
  14. data/src/main/java/com/treasuredata/api/TdApiClientConfig.java +0 -79
  15. data/src/main/java/com/treasuredata/api/TdApiConflictException.java +0 -10
  16. data/src/main/java/com/treasuredata/api/TdApiConstants.java +0 -10
  17. data/src/main/java/com/treasuredata/api/TdApiException.java +0 -20
  18. data/src/main/java/com/treasuredata/api/TdApiExecutionException.java +0 -10
  19. data/src/main/java/com/treasuredata/api/TdApiExecutionInterruptedException.java +0 -16
  20. data/src/main/java/com/treasuredata/api/TdApiExecutionTimeoutException.java +0 -18
  21. data/src/main/java/com/treasuredata/api/TdApiNotFoundException.java +0 -10
  22. data/src/main/java/com/treasuredata/api/TdApiResponseException.java +0 -32
  23. data/src/main/java/com/treasuredata/api/model/TDArrayColumnType.java +0 -80
  24. data/src/main/java/com/treasuredata/api/model/TDBulkImportSession.java +0 -157
  25. data/src/main/java/com/treasuredata/api/model/TDColumn.java +0 -129
  26. data/src/main/java/com/treasuredata/api/model/TDColumnType.java +0 -23
  27. data/src/main/java/com/treasuredata/api/model/TDColumnTypeDeserializer.java +0 -128
  28. data/src/main/java/com/treasuredata/api/model/TDDatabase.java +0 -49
  29. data/src/main/java/com/treasuredata/api/model/TDDatabaseList.java +0 -24
  30. data/src/main/java/com/treasuredata/api/model/TDMapColumnType.java +0 -88
  31. data/src/main/java/com/treasuredata/api/model/TDPrimitiveColumnType.java +0 -61
  32. data/src/main/java/com/treasuredata/api/model/TDTable.java +0 -64
  33. data/src/main/java/com/treasuredata/api/model/TDTableList.java +0 -33
  34. data/src/main/java/com/treasuredata/api/model/TDTablePermission.java +0 -50
  35. data/src/main/java/com/treasuredata/api/model/TDTableSchema.java +0 -44
  36. data/src/main/java/com/treasuredata/api/model/TDTableType.java +0 -37
  37. data/src/test/java/com/treasuredata/api/TestTdApiClient.java +0 -79
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-output-td
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Muga Nishizawa
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-02-29 00:00:00.000000000 Z
11
+ date: 2016-03-03 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -59,30 +59,6 @@ files:
59
59
  - gradlew.bat
60
60
  - lib/embulk/output/td.rb
61
61
  - settings.gradle
62
- - src/main/java/com/treasuredata/api/TdApiClient.java
63
- - src/main/java/com/treasuredata/api/TdApiClientConfig.java
64
- - src/main/java/com/treasuredata/api/TdApiConflictException.java
65
- - src/main/java/com/treasuredata/api/TdApiConstants.java
66
- - src/main/java/com/treasuredata/api/TdApiException.java
67
- - src/main/java/com/treasuredata/api/TdApiExecutionException.java
68
- - src/main/java/com/treasuredata/api/TdApiExecutionInterruptedException.java
69
- - src/main/java/com/treasuredata/api/TdApiExecutionTimeoutException.java
70
- - src/main/java/com/treasuredata/api/TdApiNotFoundException.java
71
- - src/main/java/com/treasuredata/api/TdApiResponseException.java
72
- - src/main/java/com/treasuredata/api/model/TDArrayColumnType.java
73
- - src/main/java/com/treasuredata/api/model/TDBulkImportSession.java
74
- - src/main/java/com/treasuredata/api/model/TDColumn.java
75
- - src/main/java/com/treasuredata/api/model/TDColumnType.java
76
- - src/main/java/com/treasuredata/api/model/TDColumnTypeDeserializer.java
77
- - src/main/java/com/treasuredata/api/model/TDDatabase.java
78
- - src/main/java/com/treasuredata/api/model/TDDatabaseList.java
79
- - src/main/java/com/treasuredata/api/model/TDMapColumnType.java
80
- - src/main/java/com/treasuredata/api/model/TDPrimitiveColumnType.java
81
- - src/main/java/com/treasuredata/api/model/TDTable.java
82
- - src/main/java/com/treasuredata/api/model/TDTableList.java
83
- - src/main/java/com/treasuredata/api/model/TDTablePermission.java
84
- - src/main/java/com/treasuredata/api/model/TDTableSchema.java
85
- - src/main/java/com/treasuredata/api/model/TDTableType.java
86
62
  - src/main/java/org/embulk/output/td/FinalizableExecutorService.java
87
63
  - src/main/java/org/embulk/output/td/MsgpackGZFileBuilder.java
88
64
  - src/main/java/org/embulk/output/td/RecordWriter.java
@@ -94,6 +70,7 @@ files:
94
70
  - src/main/java/org/embulk/output/td/writer/FieldWriter.java
95
71
  - src/main/java/org/embulk/output/td/writer/FieldWriterSet.java
96
72
  - src/main/java/org/embulk/output/td/writer/IFieldWriter.java
73
+ - src/main/java/org/embulk/output/td/writer/JsonFieldWriter.java
97
74
  - src/main/java/org/embulk/output/td/writer/LongFieldWriter.java
98
75
  - src/main/java/org/embulk/output/td/writer/StringFieldWriter.java
99
76
  - src/main/java/org/embulk/output/td/writer/TimestampFieldLongDuplicator.java
@@ -101,19 +78,21 @@ files:
101
78
  - src/main/java/org/embulk/output/td/writer/TimestampStringFieldWriter.java
102
79
  - src/main/java/org/embulk/output/td/writer/UnixTimestampFieldDuplicator.java
103
80
  - src/main/java/org/embulk/output/td/writer/UnixTimestampLongFieldWriter.java
104
- - src/test/java/com/treasuredata/api/TestTdApiClient.java
105
81
  - src/test/java/org/embulk/output/td/TestRecordWriter.java
106
82
  - src/test/java/org/embulk/output/td/TestTdOutputPlugin.java
107
83
  - src/test/java/org/embulk/output/td/TestTimeValueGenerator.java
108
84
  - src/test/java/org/embulk/output/td/writer/TestFieldWriterSet.java
109
- - classpath/embulk-output-td-0.2.2.jar
110
- - classpath/javassist-3.18.1-GA.jar
85
+ - classpath/embulk-output-td-0.3.0.jar
86
+ - classpath/hamcrest-core-1.1.jar
87
+ - classpath/jackson-datatype-json-org-2.4.4.jar
111
88
  - classpath/jetty-client-9.2.2.v20140723.jar
112
89
  - classpath/jetty-http-9.2.2.v20140723.jar
113
90
  - classpath/jetty-io-9.2.2.v20140723.jar
114
91
  - classpath/jetty-util-9.2.2.v20140723.jar
92
+ - classpath/json-20090211_1.jar
115
93
  - classpath/json-simple-1.1.1.jar
116
- - classpath/msgpack-0.6.11.jar
94
+ - classpath/junit-4.10.jar
95
+ - classpath/td-client-0.7.8.jar
117
96
  homepage: https://github.com/treasure-data/embulk-output-td
118
97
  licenses:
119
98
  - Apache 2.0
@@ -1,506 +0,0 @@
1
- package com.treasuredata.api;
2
-
3
- import com.fasterxml.jackson.databind.DeserializationFeature;
4
- import com.fasterxml.jackson.databind.ObjectMapper;
5
- import com.google.common.annotations.VisibleForTesting;
6
- import com.google.common.base.Throwables;
7
- import com.google.common.collect.ImmutableMap;
8
- import com.treasuredata.api.model.TDBulkImportSession;
9
- import com.treasuredata.api.model.TDColumn;
10
- import com.treasuredata.api.model.TDDatabase;
11
- import com.treasuredata.api.model.TDDatabaseList;
12
- import com.treasuredata.api.model.TDTable;
13
- import com.treasuredata.api.model.TDTableList;
14
- import com.treasuredata.api.model.TDTableType;
15
- import org.eclipse.jetty.client.HttpClient;
16
- import org.eclipse.jetty.client.HttpProxy;
17
- import org.eclipse.jetty.client.Origin;
18
- import org.eclipse.jetty.client.ProxyConfiguration;
19
- import org.eclipse.jetty.client.api.ContentResponse;
20
- import org.eclipse.jetty.client.api.Request;
21
- import org.eclipse.jetty.client.util.InputStreamContentProvider;
22
- import org.eclipse.jetty.client.util.InputStreamResponseListener;
23
- import org.eclipse.jetty.client.util.StringContentProvider;
24
- import org.eclipse.jetty.http.HttpMethod;
25
- import org.eclipse.jetty.util.HttpCookieStore;
26
- import org.eclipse.jetty.util.ssl.SslContextFactory;
27
-
28
- import javax.annotation.PostConstruct;
29
- import javax.annotation.PreDestroy;
30
- import java.io.ByteArrayOutputStream;
31
- import java.io.Closeable;
32
- import java.io.File;
33
- import java.io.IOException;
34
- import java.io.InputStream;
35
- import java.io.UnsupportedEncodingException;
36
- import java.net.URLEncoder;
37
- import java.security.MessageDigest;
38
- import java.security.NoSuchAlgorithmException;
39
- import java.text.SimpleDateFormat;
40
- import java.util.Collections;
41
- import java.util.Date;
42
- import java.util.List;
43
- import java.util.Locale;
44
- import java.util.Map;
45
- import java.util.concurrent.ExecutionException;
46
- import java.util.concurrent.TimeUnit;
47
- import java.util.concurrent.TimeoutException;
48
-
49
- public class TdApiClient
50
- implements Closeable
51
- {
52
- private final String apiKey;
53
- private final TdApiClientConfig config;
54
- private final HttpClient http;
55
- private final ObjectMapper objectMapper;
56
-
57
- public TdApiClient(String apiKey, TdApiClientConfig config)
58
- {
59
- this.apiKey = apiKey;
60
- this.config = config;
61
-
62
- objectMapper = new ObjectMapper();
63
- objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
64
-
65
- SslContextFactory sslContextFactory = new SslContextFactory();
66
- http = new HttpClient(sslContextFactory);
67
- http.setConnectTimeout(10 * 1000); // TODO get from options
68
- http.setIdleTimeout(60 * 1000); // TODO get from options
69
- http.setMaxConnectionsPerDestination(10); // TODO get from options
70
- http.setCookieStore(new HttpCookieStore.Empty());
71
-
72
- // ProxyConfiguration
73
- if (config.getHttpProxyConfig().isPresent()) {
74
- TdApiClientConfig.HttpProxyConfig httpProxyConfig = config.getHttpProxyConfig().get();
75
- String host = httpProxyConfig.getHost();
76
- int port = httpProxyConfig.getPort();
77
- boolean isSecure = httpProxyConfig.isSecure();
78
-
79
- ProxyConfiguration proxyConfig = http.getProxyConfiguration();
80
- proxyConfig.getProxies().add(new HttpProxy(new Origin.Address(host, port), isSecure));
81
- }
82
- }
83
-
84
- private TdApiClient(TdApiClient copy, String apiKey)
85
- {
86
- this.apiKey = apiKey;
87
- this.config = copy.config;
88
- this.http = copy.http;
89
- this.objectMapper = copy.objectMapper;
90
- }
91
-
92
- public TdApiClient withApikey(String apikey)
93
- {
94
- return new TdApiClient(this, apikey);
95
- }
96
-
97
- @PostConstruct
98
- public void start() throws IOException
99
- {
100
- try {
101
- http.start();
102
- }
103
- catch (Exception e) {
104
- throw new IOException("Failed to start http client", e);
105
- }
106
- }
107
-
108
- @PreDestroy
109
- public void close()
110
- {
111
- try {
112
- http.stop();
113
- }
114
- catch (Exception e) {
115
- throw new RuntimeException("Failed to stop http client", e);
116
- }
117
- }
118
-
119
- public List<TDDatabase> getDatabases()
120
- {
121
- Request request = prepareExchange(HttpMethod.GET,
122
- buildUrl("/v3/database/list"));
123
- ContentResponse response = executeExchange(request);
124
- TDDatabaseList databaseList = parseResponse(response.getContent(), TDDatabaseList.class);
125
- return databaseList.getDatabases();
126
- }
127
-
128
- public TDDatabase createDatabase(String databaseName)
129
- {
130
- Request request = prepareExchange(HttpMethod.POST,
131
- buildUrl("/v3/database/create", databaseName));
132
- ContentResponse response = executeExchange(request);
133
- TDDatabase database = parseResponse(response.getContent(), TDDatabase.class);
134
- return database;
135
- }
136
-
137
- public List<TDTable> getTables(String databaseName)
138
- {
139
- Request request = prepareExchange(HttpMethod.GET,
140
- buildUrl("/v3/table/list/", databaseName));
141
- ContentResponse response = executeExchange(request);
142
- TDTableList tables = parseResponse(response.getContent(), TDTableList.class);
143
- return tables.getTables();
144
- }
145
-
146
- public TDTable createTable(String databaseName, String tableName)
147
- {
148
- return createTable(databaseName, tableName, TDTableType.LOG);
149
- }
150
-
151
- public TDTable createTable(String databaseName, String tableName, TDTableType tableType)
152
- {
153
- Request request = prepareExchange(HttpMethod.POST,
154
- buildUrl("/v3/table/create", databaseName, tableName, tableType.name().toLowerCase()));
155
- ContentResponse response = executeExchange(request);
156
- TDTable table = parseResponse(response.getContent(), TDTable.class);
157
- return table;
158
- }
159
-
160
- public void deleteTable(String databaseName, String tableName)
161
- throws IOException
162
- {
163
- Request request = prepareExchange(HttpMethod.POST,
164
- buildUrl("/v3/table/delete", databaseName, tableName));
165
- ContentResponse response = executeExchange(request);
166
- }
167
-
168
- public void renameTable(String databaseName, String oldName, String newName, boolean overwrite)
169
- {
170
- Request request = prepareExchange(HttpMethod.POST,
171
- buildUrl("/v3/table/rename", databaseName, oldName, newName),
172
- ImmutableMap.<String, String>of(),
173
- ImmutableMap.of("overwrite", Boolean.toString(overwrite)));
174
- ContentResponse response = executeExchange(request);
175
- }
176
-
177
- public void updateSchema(String databaseName, String tableName, List<TDColumn> newSchema)
178
- {
179
- Request request = prepareExchange(HttpMethod.POST,
180
- buildUrl("/v3/table/update-schema", databaseName, tableName),
181
- ImmutableMap.<String, String>of(),
182
- ImmutableMap.of("schema", formatRequestParameterObject(newSchema)));
183
- ContentResponse response = executeExchange(request);
184
- }
185
-
186
- public void createBulkImportSession(String sessionName, String databaseName, String tableName)
187
- {
188
- Request request = prepareExchange(HttpMethod.POST,
189
- buildUrl("/v3/bulk_import/create", sessionName, databaseName, tableName));
190
- ContentResponse response = executeExchange(request);
191
- // TODO return TDBulkImportSession
192
- }
193
-
194
- public TDBulkImportSession getBulkImportSession(String sessionName)
195
- {
196
- Request request = prepareExchange(HttpMethod.GET,
197
- buildUrl("/v3/bulk_import/show", sessionName));
198
- ContentResponse response = executeExchange(request);
199
- TDBulkImportSession session = parseResponse(response.getContent(), TDBulkImportSession.class);
200
- return session;
201
- }
202
-
203
- @Deprecated
204
- public void uploadBulkImport(String sessionName, File path)
205
- throws IOException
206
- {
207
- String name = path.getName().replace(".", "_");
208
- Request request = prepareExchange(HttpMethod.PUT,
209
- buildUrl("/v3/bulk_import/upload_part", sessionName, name));
210
- request.file(path.toPath());
211
- ContentResponse response = executeExchange(request);
212
- }
213
-
214
- public void uploadBulkImportPart(String sessionName, String uniquePartName, File path)
215
- throws IOException
216
- {
217
- Request request = prepareExchange(HttpMethod.PUT,
218
- buildUrl("/v3/bulk_import/upload_part", sessionName, uniquePartName));
219
- request.file(path.toPath());
220
- ContentResponse response = executeExchange(request);
221
- }
222
-
223
- public void freezeBulkImportSession(String sessionName)
224
- {
225
- Request request = prepareExchange(HttpMethod.POST,
226
- buildUrl("/v3/bulk_import/freeze", sessionName));
227
- ContentResponse response = executeExchange(request);
228
- }
229
-
230
- public void performBulkImportSession(String sessionName, int priority)
231
- {
232
- Request request = prepareExchange(HttpMethod.POST,
233
- buildUrl("/v3/bulk_import/perform", sessionName),
234
- ImmutableMap.<String, String>of(),
235
- ImmutableMap.of("priority", String.valueOf(priority)));
236
- ContentResponse response = executeExchange(request);
237
- }
238
-
239
- public void commitBulkImportSession(String sessionName)
240
- {
241
- Request request = prepareExchange(HttpMethod.POST,
242
- buildUrl("/v3/bulk_import/commit", sessionName));
243
- ContentResponse response = executeExchange(request);
244
- }
245
-
246
- public void deleteBulkImportSession(String sessionName)
247
- {
248
- Request request = prepareExchange(HttpMethod.POST,
249
- buildUrl("/v3/bulk_import/delete", sessionName));
250
- ContentResponse response = executeExchange(request);
251
- }
252
-
253
- public InputStream getBulkImportErrorRecords(String sessionName)
254
- {
255
- // TODO use td-client-java v0.7
256
-
257
- Request request = prepareExchange(HttpMethod.GET,
258
- buildUrl("/v3/bulk_import/error_records", sessionName));
259
- InputStreamResponseListener listener = new InputStreamResponseListener();
260
- request.send(listener);
261
- try {
262
- listener.get(60000, TimeUnit.MILLISECONDS); // 60 sec.
263
- return listener.getInputStream();
264
- }
265
- catch (InterruptedException | ExecutionException | TimeoutException e) {
266
- throw Throwables.propagate(e);
267
- }
268
- }
269
-
270
- private Request prepareExchange(HttpMethod method, String url)
271
- {
272
- return prepareExchange(method, url, Collections.<String, String>emptyMap(),
273
- Collections.<String, String>emptyMap());
274
- }
275
-
276
- private Request prepareExchange(HttpMethod method,
277
- String url, Map<String, String> headers,
278
- Map<String, String> query)
279
- {
280
- String queryString = null;
281
- if (!query.isEmpty()) {
282
- StringBuilder sb = new StringBuilder();
283
- for (Map.Entry<String, String> entry : query.entrySet()) {
284
- sb.append(encode(entry.getKey())).append("=").append(encode(entry.getValue()));
285
- }
286
- queryString = sb.toString();
287
- }
288
-
289
- if (method == HttpMethod.GET && queryString != null) {
290
- url = url + "?" + queryString;
291
- }
292
- Request request = http.newRequest(url);
293
- request.method(method);
294
- request.agent(config.getAgentName());
295
- request.header("Authorization", "TD1 " + apiKey);
296
- //request.timeout(60, TimeUnit.SECONDS);
297
- for (Map.Entry<String, String> entry : headers.entrySet()) {
298
- request.header(entry.getKey(), entry.getValue());
299
- }
300
- String dateHeader = setDateHeader(request);
301
- if (method != HttpMethod.GET && queryString != null) {
302
- request.content(new StringContentProvider(queryString),
303
- "application/x-www-form-urlencoded");
304
- }
305
-
306
- return request;
307
- }
308
-
309
- private static String encode(String s)
310
- {
311
- try {
312
- return URLEncoder.encode(s, "UTF-8");
313
- }
314
- catch (UnsupportedEncodingException e) {
315
- throw new AssertionError(e);
316
- }
317
- }
318
-
319
- private static final ThreadLocal<SimpleDateFormat> RFC2822_FORMAT =
320
- new ThreadLocal<SimpleDateFormat>() {
321
- @Override
322
- protected SimpleDateFormat initialValue()
323
- {
324
- return new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
325
- }
326
- };
327
-
328
- private static String setDateHeader(Request request)
329
- {
330
- Date currentDate = new Date();
331
- String dateHeader = RFC2822_FORMAT.get().format(currentDate);
332
- request.header("Date", dateHeader);
333
- return dateHeader;
334
- }
335
-
336
- private static final ThreadLocal<MessageDigest> SHA1 =
337
- new ThreadLocal<MessageDigest>() {
338
- @Override
339
- protected MessageDigest initialValue()
340
- {
341
- try {
342
- return MessageDigest.getInstance("SHA-1");
343
- }
344
- catch (NoSuchAlgorithmException e) {
345
- throw new RuntimeException("SHA-1 digest algorithm must be available but not found", e);
346
- }
347
- }
348
- };
349
-
350
- private static final char[] hexChars = new char[16];
351
- static {
352
- for (int i = 0; i < 16; i++) {
353
- hexChars[i] = Integer.toHexString(i).charAt(0);
354
- }
355
- }
356
-
357
- @VisibleForTesting
358
- static String sha1HexFromString(String string)
359
- {
360
- MessageDigest sha1 = SHA1.get();
361
- sha1.reset();
362
- sha1.update(string.getBytes());
363
- byte[] bytes = sha1.digest();
364
-
365
- // convert binary to hex string
366
- char[] array = new char[bytes.length * 2];
367
- for (int i = 0; i < bytes.length; i++) {
368
- int b = (int) bytes[i];
369
- array[i * 2] = hexChars[(b & 0xf0) >> 4];
370
- array[i * 2 + 1] = hexChars[b & 0x0f];
371
- }
372
- return new String(array);
373
- }
374
-
375
- private String buildUrl(String path, String... params)
376
- {
377
- StringBuilder sb = new StringBuilder();
378
- sb.append(config.getUseSsl() ? "https://" : "http://");
379
- sb.append(config.getEndpoint());
380
- sb.append(path);
381
- try {
382
- for (String param : params) {
383
- sb.append("/");
384
- sb.append(URLEncoder.encode(param, "UTF-8"));
385
- }
386
- }
387
- catch (UnsupportedEncodingException ex) {
388
- throw new AssertionError(ex);
389
- }
390
- return sb.toString();
391
- }
392
-
393
- private ContentResponse executeExchange(Request request)
394
- {
395
- int retryLimit = 10;
396
- int retryWait = 1000;
397
-
398
- Exception firstException = null;
399
-
400
- try {
401
- while (true) {
402
- Exception exception;
403
-
404
- try {
405
- ContentResponse response = request.send();
406
-
407
- int status = response.getStatus();
408
- switch(status) {
409
- case 200:
410
- return response;
411
- case 404:
412
- throw new TdApiNotFoundException(status, response.getContent());
413
- case 409:
414
- throw new TdApiConflictException(status, response.getContent());
415
- }
416
-
417
- if (status / 100 != 5) { // not 50x
418
- throw new TdApiResponseException(status, response.getContent());
419
- }
420
-
421
- // retry on 50x and other errors
422
- exception = new TdApiResponseException(status, response.getContent());
423
-
424
- }
425
- catch (TdApiException e) {
426
- throw e;
427
-
428
- }
429
- catch (Exception e) {
430
- // retry on RuntimeException
431
- exception = e;
432
- }
433
-
434
- if (firstException == null) {
435
- firstException = exception;
436
- }
437
-
438
- if (retryLimit <= 0) {
439
- if (firstException instanceof TdApiException) {
440
- throw (TdApiException) firstException;
441
- }
442
- throw new TdApiExecutionException(firstException);
443
- }
444
-
445
- retryLimit -= 1;
446
- Thread.sleep(retryWait);
447
- retryWait *= 2;
448
- }
449
- }
450
- catch (InterruptedException e) {
451
- throw new TdApiExecutionInterruptedException(e);
452
- }
453
- }
454
-
455
- private String formatRequestParameterObject(Object obj)
456
- {
457
- ByteArrayOutputStream bo = new ByteArrayOutputStream();
458
- try {
459
- objectMapper.writeValue(bo, obj);
460
- return new String(bo.toByteArray(), "UTF-8");
461
- }
462
- catch (UnsupportedEncodingException ex) {
463
- throw new AssertionError(ex);
464
- }
465
- catch (IOException ex) {
466
- throw new RuntimeException(ex);
467
- }
468
- finally {
469
- try {
470
- bo.close();
471
- }
472
- catch (IOException ex) {
473
- throw new RuntimeException(ex);
474
- }
475
- }
476
- }
477
-
478
- private byte[] formatPostRequestContent(String... kvs)
479
- {
480
- try {
481
- StringBuilder sb = new StringBuilder();
482
- for (int i = 0; i < kvs.length; i += 2) {
483
- if (i > 0) {
484
- sb.append("&");
485
- }
486
- sb.append(encode(kvs[i]))
487
- .append("=")
488
- .append(encode(kvs[i + 1]));
489
- }
490
- return sb.toString().getBytes("UTF-8");
491
- }
492
- catch (UnsupportedEncodingException ex) {
493
- throw new AssertionError(ex);
494
- }
495
- }
496
-
497
- private <T> T parseResponse(byte[] content, Class<T> valueType)
498
- {
499
- try {
500
- return objectMapper.readValue(content, valueType);
501
- }
502
- catch (IOException ex) {
503
- throw new RuntimeException(ex);
504
- }
505
- }
506
- }