embulk-input-s3 0.2.19 → 0.2.21

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 3c9e972f5326281de40fc46190dc3d268282b34e
4
- data.tar.gz: 0c63221f881710e6c4a18dbf10ab73be701193ff
3
+ metadata.gz: 4bd7ca7dab8a4d3a6f25af6a33cf367965693e30
4
+ data.tar.gz: 4d3a8175e1d6ce32eaa780a44d8de66849ae34ca
5
5
  SHA512:
6
- metadata.gz: 3983830d6e700a3b3e0a2cdadd063613c4ff41b39e01c96c00c2f8a33515fd8d8be601c644184119bb87e46d1eab394869e91cf1c557c6420ef022f40a93b31e
7
- data.tar.gz: 27471ec5bbc698865ab44d2d4ca94b2074c7589c5c9c0ce919b3c3b5bc18b885b6566b48fb74803c99abc10c04716771a1b9faa231ff780de3740da55b468358
6
+ metadata.gz: e6aecfe225ac14c708a5f6acd7a605be5bca343f33af5379e1fa0b4a33219cf342f65976667d943b90da6c812f55a6f96680659db39752a32d91c1e3abeec496
7
+ data.tar.gz: 300e89205477ae9d01122fdda478b777b11605eb0302a9f2afee8ee536ef2a31b76f1001572800eca4f905452f8b894aad0bf6f3555bf5783e4bd816c3ce3151
@@ -4,6 +4,7 @@ import com.amazonaws.AmazonServiceException;
4
4
  import com.amazonaws.ClientConfiguration;
5
5
  import com.amazonaws.Protocol;
6
6
  import com.amazonaws.auth.AWSCredentialsProvider;
7
+ import com.amazonaws.retry.PredefinedRetryPolicies;
7
8
  import com.amazonaws.services.s3.AmazonS3;
8
9
  import com.amazonaws.services.s3.AmazonS3ClientBuilder;
9
10
  import com.amazonaws.services.s3.model.GetObjectMetadataRequest;
@@ -177,11 +178,12 @@ public abstract class AbstractS3FileInputPlugin
177
178
  {
178
179
  ClientConfiguration clientConfig = new ClientConfiguration();
179
180
 
181
+ /** PLT-9886: disable built-in retry*/
180
182
  //clientConfig.setProtocol(Protocol.HTTP);
181
- clientConfig.setMaxConnections(50); // SDK default: 50
182
- clientConfig.setMaxErrorRetry(3); // SDK default: 3
183
- clientConfig.setSocketTimeout(8 * 60 * 1000); // SDK default: 50*1000
184
-
183
+ // clientConfig.setMaxConnections(50); // SDK default: 50
184
+ // clientConfig.setMaxErrorRetry(3); // SDK default: 3
185
+ // clientConfig.setSocketTimeout(8 * 60 * 1000); // SDK default: 50*1000
186
+ clientConfig.setRetryPolicy(PredefinedRetryPolicies.NO_RETRY_POLICY);
185
187
  // set http proxy
186
188
  if (task.getHttpProxy().isPresent()) {
187
189
  setHttpProxyInAwsClient(clientConfig, task.getHttpProxy().get());
@@ -283,7 +285,7 @@ public abstract class AbstractS3FileInputPlugin
283
285
  {
284
286
  final GetObjectMetadataRequest objectMetadataRequest = new GetObjectMetadataRequest(bucket, objectKey);
285
287
 
286
- ObjectMetadata objectMetadata = new AlwaysRetryable<ObjectMetadata>("Looking up for a single object") {
288
+ ObjectMetadata objectMetadata = new DefaultRetryable<ObjectMetadata>("Looking up for a single object") {
287
289
  @Override
288
290
  public ObjectMetadata call()
289
291
  {
@@ -337,7 +339,7 @@ public abstract class AbstractS3FileInputPlugin
337
339
  do {
338
340
  final String finalLastKey = lastKey;
339
341
  final ListObjectsRequest req = new ListObjectsRequest(bucketName, prefix, finalLastKey, null, 1024);
340
- ObjectListing ol = new AlwaysRetryable<ObjectListing>("Listing objects") {
342
+ ObjectListing ol = new DefaultRetryable<ObjectListing>("Listing objects") {
341
343
  @Override
342
344
  public ObjectListing call()
343
345
  {
@@ -403,7 +405,7 @@ public abstract class AbstractS3FileInputPlugin
403
405
  log.warn(String.format("S3 read failed. Retrying GET request with %,d bytes offset", offset), closedCause);
404
406
  request.setRange(offset, contentLength - 1); // [first, last]
405
407
 
406
- return new AlwaysRetryable<S3ObjectInputStream>("Opening the file") {
408
+ return new DefaultRetryable<S3ObjectInputStream>("Opening the file") {
407
409
  @Override
408
410
  public S3ObjectInputStream call()
409
411
  {
@@ -1,10 +1,14 @@
1
1
  package org.embulk.input.s3;
2
2
 
3
+ import com.amazonaws.AmazonServiceException;
3
4
  import com.google.common.base.Throwables;
5
+ import org.apache.http.HttpStatus;
4
6
  import org.embulk.spi.Exec;
5
7
  import org.embulk.spi.util.RetryExecutor;
6
8
  import org.slf4j.Logger;
7
9
 
10
+ import java.util.HashSet;
11
+ import java.util.Set;
8
12
  import java.util.concurrent.Callable;
9
13
 
10
14
  import static java.lang.String.format;
@@ -12,20 +16,27 @@ import static org.embulk.spi.util.RetryExecutor.RetryGiveupException;
12
16
  import static org.embulk.spi.util.RetryExecutor.Retryable;
13
17
 
14
18
  /**
15
- * Always retry, regardless the occurred exceptions,
19
+ * Retryable utility, regardless the occurred exceptions,
16
20
  * Also provide a default approach for exception propagation.
17
21
  */
18
- class AlwaysRetryable<T> implements Retryable<T>
22
+ class DefaultRetryable<T> implements Retryable<T>
19
23
  {
20
- private static final Logger log = Exec.getLogger(AlwaysRetryable.class);
21
-
24
+ private static final Logger log = Exec.getLogger(DefaultRetryable.class);
25
+ private static final Set<Integer> NONRETRYABLE_STATUS_CODES = new HashSet<Integer>(2);
26
+ private static final Set<String> NONRETRYABLE_ERROR_CODES = new HashSet<String>(1);
22
27
  private String operationName;
23
28
  private Callable<T> callable;
24
29
 
30
+ static {
31
+ NONRETRYABLE_STATUS_CODES.add(HttpStatus.SC_FORBIDDEN);
32
+ NONRETRYABLE_STATUS_CODES.add(HttpStatus.SC_METHOD_NOT_ALLOWED);
33
+ NONRETRYABLE_ERROR_CODES.add("ExpiredToken");
34
+ }
35
+
25
36
  /**
26
37
  * @param operationName the name that will be referred on logging
27
38
  */
28
- public AlwaysRetryable(String operationName)
39
+ public DefaultRetryable(String operationName)
29
40
  {
30
41
  this.operationName = operationName;
31
42
  }
@@ -34,18 +45,18 @@ class AlwaysRetryable<T> implements Retryable<T>
34
45
  * @param operationName the name that will be referred on logging
35
46
  * @param callable the operation, either define this at construction time or override the call() method
36
47
  */
37
- public AlwaysRetryable(String operationName, Callable<T> callable)
48
+ public DefaultRetryable(String operationName, Callable<T> callable)
38
49
  {
39
50
  this.operationName = operationName;
40
51
  this.callable = callable;
41
52
  }
42
53
 
43
- public AlwaysRetryable()
54
+ public DefaultRetryable()
44
55
  {
45
56
  this("Anonymous operation");
46
57
  }
47
58
 
48
- public AlwaysRetryable(Callable<T> callable)
59
+ public DefaultRetryable(Callable<T> callable)
49
60
  {
50
61
  this("Anonymous operation", callable);
51
62
  }
@@ -64,6 +75,11 @@ class AlwaysRetryable<T> implements Retryable<T>
64
75
  @Override
65
76
  public boolean isRetryableException(Exception exception)
66
77
  {
78
+ // No retry on a subset of service exceptions
79
+ if (exception instanceof AmazonServiceException) {
80
+ AmazonServiceException ase = (AmazonServiceException) exception;
81
+ return !NONRETRYABLE_STATUS_CODES.contains(ase.getStatusCode()) && !NONRETRYABLE_ERROR_CODES.contains(ase.getErrorCode());
82
+ }
67
83
  return true;
68
84
  }
69
85
 
@@ -1,11 +1,13 @@
1
1
  package org.embulk.input.s3;
2
2
 
3
+ import com.amazonaws.AmazonServiceException;
3
4
  import com.amazonaws.services.s3.AmazonS3;
4
5
  import com.amazonaws.services.s3.model.GetObjectMetadataRequest;
5
6
  import com.amazonaws.services.s3.model.ListObjectsRequest;
6
7
  import com.amazonaws.services.s3.model.ObjectListing;
7
8
  import com.amazonaws.services.s3.model.ObjectMetadata;
8
9
  import com.google.common.base.Optional;
10
+ import org.apache.http.HttpStatus;
9
11
  import org.embulk.EmbulkTestRuntime;
10
12
  import org.embulk.spi.util.RetryExecutor;
11
13
  import org.junit.Before;
@@ -83,6 +85,52 @@ public class TestAbstractS3FileInputPlugin
83
85
  retryExecutor().withRetryLimit(0));
84
86
  }
85
87
 
88
+ @Test(expected = AmazonServiceException.class)
89
+ public void listS3FileByPrefix_on_retry_gave_up_should_throw_the_original_exception_in_forbidden_code()
90
+ {
91
+ AmazonServiceException exception = new AmazonServiceException("Forbidden exception");
92
+ exception.setStatusCode(HttpStatus.SC_FORBIDDEN);
93
+ exception.setErrorType(AmazonServiceException.ErrorType.Client);
94
+
95
+ doThrow(exception).doReturn(new ObjectListing())
96
+ .when(client).listObjects(any(ListObjectsRequest.class));
97
+ FileList.Builder builder = new FileList.Builder();
98
+ dummyS3Plugin().listS3FilesByPrefix(
99
+ builder, client, "some_bucket", "some_prefix", Optional.of("last_path"), true,
100
+ retryExecutor().withRetryLimit(1));
101
+ }
102
+
103
+ @Test(expected = AmazonServiceException.class)
104
+ public void listS3FileByPrefix_on_retry_gave_up_should_throw_the_original_exception_in_methodnotallow_code()
105
+ {
106
+ AmazonServiceException exception = new AmazonServiceException("method not allow exception");
107
+ exception.setStatusCode(HttpStatus.SC_METHOD_NOT_ALLOWED);
108
+ exception.setErrorType(AmazonServiceException.ErrorType.Client);
109
+
110
+ doThrow(exception).doReturn(new ObjectListing())
111
+ .when(client).listObjects(any(ListObjectsRequest.class));
112
+ FileList.Builder builder = new FileList.Builder();
113
+ dummyS3Plugin().listS3FilesByPrefix(
114
+ builder, client, "some_bucket", "some_prefix", Optional.of("last_path"), true,
115
+ retryExecutor().withRetryLimit(1));
116
+ }
117
+
118
+ @Test(expected = AmazonServiceException.class)
119
+ public void listS3FileByPrefix_on_retry_gave_up_should_throw_the_original_exception_in_expiredToken_code()
120
+ {
121
+ AmazonServiceException exception = new AmazonServiceException("expired token exception");
122
+ exception.setStatusCode(HttpStatus.SC_BAD_REQUEST);
123
+ exception.setErrorCode("ExpiredToken");
124
+ exception.setErrorType(AmazonServiceException.ErrorType.Client);
125
+
126
+ doThrow(exception).doReturn(new ObjectListing())
127
+ .when(client).listObjects(any(ListObjectsRequest.class));
128
+ FileList.Builder builder = new FileList.Builder();
129
+ dummyS3Plugin().listS3FilesByPrefix(
130
+ builder, client, "some_bucket", "some_prefix", Optional.of("last_path"), true,
131
+ retryExecutor().withRetryLimit(1));
132
+ }
133
+
86
134
  @Test
87
135
  public void addS3DirectObject()
88
136
  {
@@ -12,10 +12,10 @@ import java.util.concurrent.Callable;
12
12
  import static java.lang.String.format;
13
13
  import static org.msgpack.core.Preconditions.checkArgument;
14
14
 
15
- public class TestAlwaysRetryable
15
+ public class TestDefaultRetryable
16
16
  {
17
17
  @Rule
18
- public EmbulkTestRuntime runtime = new EmbulkTestRuntime(); // require for AlwaysRetryable's logger
18
+ public EmbulkTestRuntime runtime = new EmbulkTestRuntime(); // require for DefaultRetryable's logger
19
19
 
20
20
  private static class Deny extends RuntimeException implements Callable
21
21
  {
@@ -71,16 +71,16 @@ public class TestAlwaysRetryable
71
71
  {
72
72
  retryExecutor()
73
73
  .withRetryLimit(0)
74
- .run(new AlwaysRetryable(Deny.until(0)));
74
+ .run(new DefaultRetryable(Deny.until(0)));
75
75
  retryExecutor()
76
76
  .withRetryLimit(1)
77
- .run(new AlwaysRetryable(Deny.until(1)));
77
+ .run(new DefaultRetryable(Deny.until(1)));
78
78
  retryExecutor()
79
79
  .withRetryLimit(2)
80
- .run(new AlwaysRetryable(Deny.until(1)));
80
+ .run(new DefaultRetryable(Deny.until(1)));
81
81
  retryExecutor()
82
82
  .withRetryLimit(3)
83
- .run(new AlwaysRetryable(Deny.until(2)));
83
+ .run(new DefaultRetryable(Deny.until(2)));
84
84
  }
85
85
 
86
86
  @Test(expected = RetryGiveupException.class)
@@ -89,14 +89,14 @@ public class TestAlwaysRetryable
89
89
  {
90
90
  retryExecutor()
91
91
  .withRetryLimit(3)
92
- .run(new AlwaysRetryable(Deny.until(4)));
92
+ .run(new DefaultRetryable(Deny.until(4)));
93
93
  }
94
94
 
95
95
  @Test(expected = Deny.class)
96
96
  @SuppressWarnings("unchecked")
97
97
  public void execute_should_unwrap_RetryGiveupException() throws Exception
98
98
  {
99
- new AlwaysRetryable(Deny.until(4))
99
+ new DefaultRetryable(Deny.until(4))
100
100
  .executeWith(retryExecutor().withRetryLimit(3));
101
101
  }
102
102
 
@@ -104,7 +104,7 @@ public class TestAlwaysRetryable
104
104
  @SuppressWarnings("unchecked")
105
105
  public void execute_should_unwrap_RetryGiveupException_but_rewrap_checked_exception_in_a_RuntimeException()
106
106
  {
107
- new AlwaysRetryable(Deny.until(4).with(new Exception("A checked exception")))
107
+ new DefaultRetryable(Deny.until(4).with(new Exception("A checked exception")))
108
108
  .executeWith(retryExecutor().withRetryLimit(3));
109
109
  }
110
110
 
@@ -114,7 +114,7 @@ public class TestAlwaysRetryable
114
114
  RetryExecutor retryExc = retryExecutor().withRetryLimit(3);
115
115
  // An explicit type parameter for operation return type is needed here,
116
116
  // Without one, javac (at least on 1.8) will fails to infer the X exception type parameter.
117
- new AlwaysRetryable<Object>() {
117
+ new DefaultRetryable<Object>() {
118
118
  @Override
119
119
  public Object call() throws IOException
120
120
  {
@@ -126,6 +126,6 @@ public class TestAlwaysRetryable
126
126
  @Test(expected = IllegalStateException.class)
127
127
  public void execute_without_an_implementation_should_throw_an_IllegalStateException()
128
128
  {
129
- new AlwaysRetryable().executeWith(retryExecutor());
129
+ new DefaultRetryable().executeWith(retryExecutor());
130
130
  }
131
131
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: embulk-input-s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.19
4
+ version: 0.2.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sadayuki Furuhashi
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-06-26 00:00:00.000000000 Z
11
+ date: 2018-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -48,34 +48,34 @@ files:
48
48
  - build.gradle
49
49
  - lib/embulk/input/s3.rb
50
50
  - src/main/java/org/embulk/input/s3/AbstractS3FileInputPlugin.java
51
- - src/main/java/org/embulk/input/s3/AlwaysRetryable.java
51
+ - src/main/java/org/embulk/input/s3/DefaultRetryable.java
52
52
  - src/main/java/org/embulk/input/s3/FileList.java
53
53
  - src/main/java/org/embulk/input/s3/HttpProxy.java
54
54
  - src/main/java/org/embulk/input/s3/RetrySupportPluginTask.java
55
55
  - src/main/java/org/embulk/input/s3/S3FileInputPlugin.java
56
56
  - src/test/java/org/embulk/input/s3/TestAbstractS3FileInputPlugin.java
57
- - src/test/java/org/embulk/input/s3/TestAlwaysRetryable.java
58
57
  - src/test/java/org/embulk/input/s3/TestAwsCredentials.java
58
+ - src/test/java/org/embulk/input/s3/TestDefaultRetryable.java
59
59
  - src/test/java/org/embulk/input/s3/TestFileList.java
60
60
  - src/test/java/org/embulk/input/s3/TestHttpProxy.java
61
61
  - src/test/java/org/embulk/input/s3/TestS3FileInputPlugin.java
62
62
  - src/test/java/org/embulk/input/s3/TestS3InputStreamReopener.java
63
63
  - src/test/resources/sample_01.csv
64
- - classpath/aws-java-sdk-core-1.11.253.jar
65
64
  - classpath/aws-java-sdk-kms-1.11.253.jar
65
+ - classpath/embulk-input-s3-0.2.21.jar
66
+ - classpath/jackson-core-2.6.7.jar
67
+ - classpath/ion-java-1.0.2.jar
66
68
  - classpath/aws-java-sdk-s3-1.11.253.jar
67
- - classpath/commons-codec-1.9.jar
68
- - classpath/embulk-input-s3-0.2.19.jar
69
- - classpath/embulk-util-aws-credentials-0.2.19.jar
70
69
  - classpath/httpclient-4.5.2.jar
70
+ - classpath/commons-codec-1.9.jar
71
+ - classpath/jmespath-java-1.11.253.jar
72
+ - classpath/jcl-over-slf4j-1.7.12.jar
73
+ - classpath/aws-java-sdk-core-1.11.253.jar
74
+ - classpath/embulk-util-aws-credentials-0.2.21.jar
75
+ - classpath/jackson-dataformat-cbor-2.6.7.jar
76
+ - classpath/jackson-databind-2.6.7.1.jar
71
77
  - classpath/httpcore-4.4.4.jar
72
- - classpath/ion-java-1.0.2.jar
73
78
  - classpath/jackson-annotations-2.6.0.jar
74
- - classpath/jackson-core-2.6.7.jar
75
- - classpath/jackson-databind-2.6.7.1.jar
76
- - classpath/jackson-dataformat-cbor-2.6.7.jar
77
- - classpath/jcl-over-slf4j-1.7.12.jar
78
- - classpath/jmespath-java-1.11.253.jar
79
79
  homepage: https://github.com/embulk/embulk-input-s3
80
80
  licenses:
81
81
  - Apache 2.0
Binary file